处置实现IDisposable的成员

时间:2010-06-11 12:25:28

标签: c# idisposable nullreferenceexception

在我的Dispose方法(如下所示)中,每次我想调用someObj.Dispose()时我都会检查someObj!= null。

这是因为我的设计不好吗? 他们是否更清楚地确定调用在对象中使用的所有成员(实现IDisposable)而不会有NullReference异常风险?

protected void Dispose(bool disposing)
        {
            if (disposing)
            {
               if (_splitTradePopupManager != null)
                {
                    _splitTradePopupManager.Dispose();
                }
             }
        }

感谢您的关注。

5 个答案:

答案 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(); 
            } 
         } 
    }