开发者

Cast type to IDisposable - Why?

开发者 https://www.devze.com 2023-02-04 02:31 出处:网络
Saw this. Why the explicit cast to IDisposable? Is this just a shorthand to ensure that IDisposable is called on exiting the using block?

Saw this. Why the explicit cast to IDisposable? Is this just a shorthand to ensure that IDisposable is called on exiting the using block?

using (proxy as IDisposable)
{
  string s = prox开发者_开发知识库y.Stuff()                                    
}


This "trick", if you can call it that, is most likely due to proxy being of a type that the compiler can't verify really implements IDisposable.

The nice thing about the using directive, is that if the parameter to it is null, then no call to Dispose will be done upon exiting the scope of the using statement.

So the code you've shown is actually short-hand for:

var disposable = proxy as IDisposable;
try
{
    string s = proxy.Stuff();
}
finally
{
    if (disposable != null)
        disposable.Dispose();
}

In other words, it says "if this object implements IDisposable, I need to dispose of it when I'm done with the following piece of code."


This could be required if you are given a proxy instance from somewhere and its static type does not implement IDisposable but you know that the real type may do and you want to make sure it will be disposed e.g.

public class Proxy : ISomeInterface, IDisposable
{
    ...
}

private ISomeInterface Create() { ... }

ISomeInterface proxy = Create();

//won't compile without `as`
using(proxy as IDisposable)
{
    ...
}


It's unnecessary as the using statement is explicitly tied to the IDisposable interface, per the MSDN docs

Provides a convenient syntax that ensures the correct use of IDisposable objects.

edit: The C# language spec (sec. 8.13) provides three possible expansions for the using statement's syntactic sugar:

A using statement of the form

using (ResourceType resource = expression) statement

corresponds to one of three possible expansions. When ResourceType is a non-nullable value type, the expansion is

{
   ResourceType resource = expression;
   try {
      statement;
   }
   finally {
      ((IDisposable)resource).Dispose();
   }
}

Otherwise, when ResourceType is a nullable value type or a reference type other than dynamic, the expansion is

{
   ResourceType resource = expression;
   try {
      statement;
   }
   finally {
      if (resource != null) ((IDisposable)resource).Dispose();
   }
}

Otherwise, when ResourceType is dynamic, the expansion is

{
   ResourceType resource = expression;
   IDisposable d = (IDisposable)resource;
   try {
      statement;
   }
   finally {
      if (d != null) d.Dispose();
   }
}

Note that in each one of these expansions the cast is done anyway, so as originally stated, the as IDisposable is unnecessary.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号