首页 > 解决方案 > How can IDisposable field be null here?

问题描述

I've a lot of examples that a disposable class disposes its disposable field with null-conditional operator like _field?.Dispose(). And Resharper also generates code with a null check.

class Foo : IDisposable
{
    private readonly Bar _bar;

    public Foo()
    {
        _bar = new Bar();
    }
    
    public void Dispose()
    {
        _bar?.Dispose();
    }
}

class Bar : IDisposable
{
    public void Dispose()
    {
    }
}

My question is why the null check on field _bar is used here? It can not be null at this point. It is not garbage collected unless the containing object is garbage collected because it holds a reference to it. And if containing object i.e. Foo object was null, we can never call .Dispose() on it because it will throw a null reference exception.

标签: c#nulldispose

解决方案


在这个特定的例子中,你是对的,_bar不能为空。这是几个因素的组合:

  • 只有一个构造函数总是初始化一个Bar对象
  • _bar是只读的,这保证以后没有人可以将其设置为空

但不难想出一个它可能为空的例子(例如,改变上述任何一个要点)。即使对于这个简单的代码示例,我已经认为Bar如果您希望这是一个干净的代码库,很可能应该注入,这会抛出您可以保证_bar不会为空的论点。

专门创建代码的 null 保护和非 null 保护变体,而不是始终防止 null 有什么好处?这需要更多的努力,您可能会选择错误的选项;有什么好处?没有什么。

因此,如果故意忽略 null 保护没有任何好处,为什么还要弄清楚是否有必要防止 null 呢?只包含空保护比花时间弄清楚在这种特殊情况下是否可能不需要空保护更容易。

另请注意,您具体指的是在线演示代码或 Resharper 生成的模板,在这两种情况下,它们都旨在覆盖广泛的受众并保持广泛适用。


推荐阅读