将类型转换为IDisposable - 为什么?

时间:2011-01-14 20:34:01

标签: c# idisposable

看到这个。为什么显式转换为IDisposable?这只是确保在退出使用块时调用IDisposable的简写吗?

using (proxy as IDisposable)
{
  string s = proxy.Stuff()                                    
}

3 个答案:

答案 0 :(得分:26)

这个“技巧”,如果可以调用它,很可能是由于proxy是编译器无法验证的类型,实际上是IDisposable

关于using指令的好处是,如果它的参数是null,那么在退出{{1}的范围时不会调用Dispose声明。

因此,您展示的代码实际上是简写:

using

换句话说,它说“如果这个对象实现了IDisposable,当我完成下面的代码时,我需要处理它。”

答案 1 :(得分:4)

如果您从某个地方获得proxy实例并且其静态类型未实现IDisposable,但您知道实际类型可能会执行此操作并且您希望确保它将是处置,例如

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

private ISomeInterface Create() { ... }

ISomeInterface proxy = Create();

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

答案 2 :(得分:3)

这是不必要的,因为using语句明确与IDisposable界面绑定,per the MSDN docs

  

提供方便的语法,确保正确使用IDisposable对象。

编辑C# language spec(第8.13节)为using语句的句法糖提供了三种可能的扩展:

  

表格的使用声明

using (ResourceType resource = expression) statement
  

对应于三种可能的扩展之一。当ResourceType是不可为空的值类型时,扩展名为

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

否则,当ResourceType是可空值类型或动态以外的引用类型时,扩展为

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

否则,当ResourceType为动态时,扩展为

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

请注意,在这些扩展中的每一个中,无论如何都要完成转换,因此如上所述,as IDisposable是不必要的。