在我的Dispose方法(如下所示)中,每次我想调用someObj.Dispose()时我都会检查someObj!= null。
这是因为我的设计不好吗? 他们是否更清楚地确定调用在对象中使用的所有成员(实现IDisposable)而不会有NullReference异常风险?
protected void Dispose(bool disposing)
{
if (disposing)
{
if (_splitTradePopupManager != null)
{
_splitTradePopupManager.Dispose();
}
}
}
感谢您的关注。
答案 0 :(得分:10)
我喜欢@Dan Tao的解决方案,但它作为一种扩展方法更好,imo:
public static void SafeDispose(this IDisposable obj)
{
if (obj != null)
obj.Dispose();
}
现在,您只需在程序中的任何member.SafeDispose()
上致电IDisposable
,无需担心。 :)
答案 1 :(得分:5)
也许其他人可以参与其中,但我个人并不认为这是一个设计缺陷 - 只是最安全的方式。
也就是说,没有什么可以阻止您以方便的方式包裹null
支票和Dispose
电话:
private void DisposeMember(IDisposable member)
{
if (member != null)
member.Dispose();
}
然后您的Dispose
方法可能看起来更清晰:
protected void Dispose(bool disposing)
{
if (disposing)
{
DisposeMember(_splitTradePopupManager);
DisposeMember(_disposableMember2);
DisposeMember(_disposableMember3);
}
}
作为额外的奖励,这也解决了原始代码中潜在的竞争条件。如果在多线程上下文中运行,if (_field != null) _field.Dispose()
模式可以在检查和处置之间NullReferenceException
设置为_field
时产生null
(很少见,但可能)。将_field
作为参数传递给DisposeMember
等方法会将对该方法中的局部变量的引用复制,从而消除这种可能性,不太可能发生。
答案 2 :(得分:0)
只有你知道这个的答案!
在没有看到整个班级的情况下,其他人很难判断在调用Dispose
时这些成员是否可能为空。
(当然,作为一般规则,引用类型或可空值类型总是可以为null,因此最好始终包括那些空检查。)
答案 3 :(得分:0)
我能想到的唯一另一个选择是创建一个DisposeParameter
辅助方法,该方法有一个对象作为参数,只检查它是否为null,否则为Dispose它。这样你只需要一行代码来处理它,但我不确定它是否会使它更具可读性。
答案 4 :(得分:-1)
试试这个。
protected void Dispose(bool disposing)
{
if (disposing)
{
//for all members..
if (null != member && member is IDisposible)
{
member.Dispose();
}
}
}