简体   繁体   English

处置实现IDisposable的成员

[英]Disposing the members that implement IDisposable

In my Dispose methods (like the one below), everytime i want to call someObj.Dispose() i also have a check for someObj!=null. 在我的Dispose方法(如下所示)中,每次我想调用someObj.Dispose()时我都会检查someObj!= null。

Is that because of bad design on my part? 这是因为我的设计不好吗? Is their a cleaner way to ascertain that Dispose of all the members (implementing IDisposable) being used in an object is called without having a risk of NullReference exception ? 他们是否更清楚地确定在没有NullReference异常风险的情况下调用在对象中使用的所有成员(实现IDisposable)的Dispose?

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

Thanks for your interest. 谢谢你的关注。

I like @Dan Tao's solution, but it's much better as an extension method, imo: 我喜欢@Dan Tao的解决方案,但它作为一种扩展方法更好,imo:

public static void SafeDispose(this IDisposable obj)
{
    if (obj != null)
        obj.Dispose();
}

Now you can just call member.SafeDispose() on any IDisposable in your program without worry. 现在,您可以在程序中的任何IDisposable上调用member.SafeDispose() ,而无需担心。 :) :)

Maybe someone else can chime in on this, but I don't personally think it's a design flaw -- just the safest way to do it. 也许其他人可以参与其中,但我个人并不认为这是一个设计缺陷 - 只是最安全的方式。

That said, nothing's stopping you from wrapping your null check and Dispose call in a convenient method: 也就是说,没有什么能阻止你用一个方便的方法包装你的null检查和Dispose调用:

private void DisposeMember(IDisposable member)
{
    if (member != null)
        member.Dispose();
}

Then your Dispose method could look a bit cleaner: 然后您的Dispose方法可能看起来更清洁:

protected void Dispose(bool disposing)
{
    if (disposing)
    {
        DisposeMember(_splitTradePopupManager);
        DisposeMember(_disposableMember2);
        DisposeMember(_disposableMember3);
    }
}

As an added bonus, this also resolves a potential race condition in your original code. 作为额外的奖励,这也解决了原始代码中潜在的竞争条件。 If running in a multithreaded context, the if (_field != null) _field.Dispose() pattern can result in a NullReferenceException when _field is set to null between the check and the disposal (rare, but possible). 如果在多线程上下文中运行, if (_field != null) _field.Dispose()模式在检查和处理之间将_field设置为null时可能会导致NullReferenceException (很少见,但可能)。 Passing _field as an argument to a method such as DisposeMember copies the reference to a local variable in the method, eliminating this possibility, unlikely as it is. _field作为参数传递_field等方法DisposeMember引用复制到方法中的局部变量,从而消除了这种可能性,不太可能。

Only you know the answer to this one! 只有你知道这个的答案!

Without seeing your entire class it's difficult for anyone else to tell if it's possible that those members will ever be null when Dispose is called. 在没有看到整个类的情况下,其他任何人都很难判断调用Dispose时这些成员是否可能为null。

(Of course, as a general rule it's always possible for a reference type or nullable value type to be null, so it's probably good practice to always include those null checks anyway.) (当然,作为一般规则,引用类型或可空值类型总是可以为null,因此最好始终包括那些空值检查。)

The only other option I could think of would be to create a DisposeParameter helper method that has an object as it's parameter and only checks if it's null and otherwise Dispose it. 我能想到的唯一另一个选择是创建一个DisposeParameter辅助方法,它有一个对象作为它的参数,只检查它是否为null,否则Dispose它。 That way you'd only need one line of code to dispose of it, but I'm not sure if it would make it more readable. 这样你只需要一行代码来处理它,但我不确定它是否会使它更具可读性。

Try this. 试试这个。

    protected void Dispose(bool disposing) 
    { 
        if (disposing) 
        {
           //for all members.. 
           if (null != member && member is IDisposible) 
            { 
                member.Dispose(); 
            } 
         } 
    } 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM