看到这个。为什么要显式地将其转换为IDisposable?这只是一种简写,以确保在退出using块时调用IDisposable吗?
using (proxy as IDisposable)
{
string s = proxy.Stuff()
}
看到这个。为什么要显式地将其转换为IDisposable?这只是一种简写,以确保在退出using块时调用IDisposable吗?
using (proxy as IDisposable)
{
string s = proxy.Stuff()
}
这种“技巧”,如果可以这样称呼它的话,很可能是由于proxy
属于编译器无法验证真正实现了IDisposable
接口的类型。
using
指令的好处在于,如果它的参数为null
,则在退出using
语句所在作用域时不会调用Dispose
。
因此,你所展示的代码实际上是下面代码的简写:
var disposable = proxy as IDisposable;
try
{
string s = proxy.Stuff();
}
finally
{
if (disposable != null)
disposable.Dispose();
}
换句话说,它表示“如果这个对象实现了IDisposable接口,在我完成以下代码块后,我需要对其进行处理。”
如果您从某个地方获取了一个proxy
实例,它的静态类型没有实现IDisposable
,但是您知道真正的类型可能会这样做,并且希望确保它将被处理,那么可能需要执行此操作。
public class Proxy : ISomeInterface, IDisposable
{
...
}
private ISomeInterface Create() { ... }
ISomeInterface proxy = Create();
//won't compile without `as`
using(proxy as IDisposable)
{
...
}
这是不必要的,因为using
语句与IDisposable
接口有明确的关联,根据MSDN文档。
提供了一种方便的语法,以确保正确使用
IDisposable
对象。
编辑:C#语言规范(第8.13节)提供了using
语句语法糖的三种可能扩展:
形如的
using
语句:
using (ResourceType resource = expression) statement
当ResourceType是一个非空值类型时,它对应于三种可能的扩展。
{
ResourceType resource = expression;
try {
statement;
}
finally {
((IDisposable)resource).Dispose();
}
}
{
ResourceType resource = expression;
try {
statement;
}
finally {
if (resource != null) ((IDisposable)resource).Dispose();
}
}
{
ResourceType resource = expression;
IDisposable d = (IDisposable)resource;
try {
statement;
}
finally {
if (d != null) d.Dispose();
}
}
as IDisposable
是不必要的。
proxy
扩展了 IDisposable。 - user1228IDisposable
接口,而是要知道它 可能 实现了该接口,在需要时必须进行处理。请注意,如果工厂返回的类型可能需要处理但未实现或继承IDisposable
接口,则应将其视为极端反模式,但如果代码必须与此类工厂一起使用,则using(foo as IDisposable)
可能是最佳模式。 - supercat