我有很多例子表明一次性类使用空条件运算符(如 _field?.Dispose()
)处理其一次性字段。 Resharper 还会生成带有空检查的代码。
class Foo : IDisposable
{
private readonly Bar _bar;
public Foo()
{
_bar = new Bar();
}
public void Dispose()
{
_bar?.Dispose();
}
}
class Bar : IDisposable
{
public void Dispose()
{
}
}
我的问题是为什么这里使用字段 _bar
的空检查?此时它不能为空。它不会被垃圾回收,除非包含对象被垃圾回收,因为它持有对它的引用。如果包含对象,即 Foo
对象为空,我们永远不能对其调用 .Dispose()
,因为它会抛出空引用异常。
最佳答案
你说得对,_bar
在此特定示例中不能为 null。这是几个因素的组合:
- 只有一个构造函数总是初始化一个
Bar
对象 _bar
是只读的,这保证之后没有人可以将它设置为 null
但不难想出一个它可能为 null 的示例(例如,更改上述任何要点)。即使对于这个简单的代码示例,我也已经争辩说,如果您希望它成为一个干净的代码库,则很可能应该注入(inject) Bar
,这抛出了您可以保证 _bar 的论点
不会为空。
专门创建代码的 null 保护和非 null 保护变体与始终防止 null 相比有什么好处?这需要更多的努力,您可能会选择错误的选项;有什么好处?什么都没有。
因此,如果故意省略 null 保护没有任何好处,为什么还要费心弄清楚是否有必要防止 null 呢?只包含空值保护比花时间弄清楚在这种特定情况下是否不需要空值保护要容易得多。
另请注意,您具体指的是在线演示代码或 Resharper 生成的模板,这两种情况都旨在覆盖广泛的受众并保持广泛适用。
关于c# - IDisposable 字段怎么能在这里为空?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64513257/