13

如果资源没有实现 IDisposable,下面的代码会起作用吗?

  T resource = new T();
  using (resource as IDisposable)
  {
     ...
  }
4

8 回答 8

16

是的。一个using语句检查它是否被给出null,如果是,则避免尝试调用Dispose

从 C# 3 规范的第 8.13 节:

using 语句被翻译成三个部分:获取、使用和处置。资源的使用隐式包含在包含 finally 子句的 try 语句中。这个 finally 子句处理资源。如果获取了 null 资源,则不会调用 Dispose,也不会引发异常。

于 2009-04-01T21:33:56.043 回答
10

是的,它会工作,检查这个正在运行的测试:

[TestMethod]
public void TestMethod8()
{
    using (new MyClass() as IDisposable)
    {
    }
}
public class MyClass { }

它只是运行没有任何问题。如果相应的类实现了 IDisposable ,它将调用它,否则它仍然可以工作/运行:)。

更新:正如其他人所说,我也想知道你想给它什么用途。我的猜测是你有一个类似工厂的东西,可以从不同的类中获取实例,这些实例可能是一次性的,也可能不是一次性的:)。

于 2009-04-01T21:32:42.723 回答
2

它应该可以正常工作,即使不是处理资源的“正确”方法。该using语句只是语法糖

IDisposable o = ...;

try
{
  // ...
}
finally
{
  if (o != null)
    o.Dispose(true);
}

因此,如果 o 从未实现IDisposable,它将在using语句中为 null 并且它会尝试调用Dispose它。

于 2009-04-01T21:35:55.727 回答
2

在测试代​​码时,它似乎不会导致任何编译或运行时错误。

从语言定义(见第 8.13 节):-

如果获取了 null 资源,则不会调用 Dispose,也不会引发异常。

如果该类型不能转换为 IDisposible,则 as 运算符会将资源转换为 null,并且封装在 using 块中的代码将执行得非常好,其行为与未将其包含在 using 块中的行为完全相同。

简而言之,您的问题的答案是肯定的。

于 2009-04-01T21:40:22.377 回答
1

如果通过“它会工作”你的意思是你会得到一个运行时错误吗?不,你不会。

于 2009-04-01T21:31:38.653 回答
1

这有什么用?有什么好处?有什么好处?

using 语句将确保调用 Dispose 方法,但如果您的对象没有实现 IDisposable,我认为这样做没有用吗?它会工作(如,它不会抛出运行时异常并且它会编译),我刚刚在这里测试过但是......

使用您写下的代码,您甚至无法将资源用作 IDisposable ...

于 2009-04-01T21:33:41.083 回答
1

当类型显式实现 IDisposable 时,它​​可能很有用,在这种情况下,除非将类型强制转换为 IDisposable,否则无法直接访问该类型的 Dispose 方法,使用“as”进行安全强制转换并确保调用 Dispose。在大多数情况下,当类型显式实现 IDisposable 时,它​​会提供诸如 'Close' 之类的方法,而后者又会调用 Dispose

于 2009-04-02T07:36:04.957 回答
0

我相信编译器会在尝试调用 Dispose 之前添加检查以确定它是否为空。

http://aspnetresources.com/blog/the_very_handy_using_statement.aspx

于 2009-04-01T21:33:41.223 回答