在(可能)为 null 的对象上使用
using
语句是否安全?class Test {
IDisposable GetObject(string name) {
// returns null if not found
}
void DoSomething() {
using (IDisposable x = GetObject("invalid name")) {
if (x != null) {
// etc...
}
}
}
}
是否保证仅当对象不为空时才会调用
Dispose
,并且我不会得到NullReferenceException
?
在调用
using
之前,null
的扩展会检查该对象是否不是 Dispose
,所以是的,它是安全的。
在你的情况下,你会得到类似的东西:
IDisposable x = GetObject("invalid name");
try
{
// etc...
}
finally
{
if(x != null)
{
x.Dispose();
}
}
你应该没问题:
using ((IDisposable)null) { }
这里没有抛出异常。
旁注:不要将其与
foreach
和 IEnumerable
混淆,否则会抛出异常。
是的,在处置之前将对引用进行空检查。您可以通过在 Reflector 中查看代码来检查自己。
我遇到这个问题是因为我有一个对象,我不知道它是否需要处理,但如果需要的话就应该处理。我处理这个问题的方法是使用
IDisposable
关键字将其转换为 as
。这是一个例子:
void DoSomethingWithMyType(Func<IMyType> factory)
{
IMyType myObj = factory();
// Some but not all implementations IMyType of implement IDisposable
using (myObj as IDisposable)
{
myObject.DoSomething();
}
}
在我的示例场景中,
IMyType
是一个本身不实现IDisposable
的接口,但已知某些实现IMyType
的类实现了IDisposable
,而其他类则没有。在前一种情况下,myObj as IDisposable
表达式生成一个IDisposable
对象,当离开Dispose
块时,在该对象上调用using
。在后一种情况下,表达式产生 null
,在这种情况下什么也不会发生,最重要的是,离开 using
块时不会引发异常。
根据我的经验,你不会得到空引用异常。它将被简单地忽略。