c# - 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.
解决方案
在这个特定的例子中,你是对的,_bar
不能为空。这是几个因素的组合:
- 只有一个构造函数总是初始化一个
Bar
对象 _bar
是只读的,这保证以后没有人可以将其设置为空
但不难想出一个它可能为空的例子(例如,改变上述任何一个要点)。即使对于这个简单的代码示例,我已经认为Bar
如果您希望这是一个干净的代码库,很可能应该注入,这会抛出您可以保证_bar
不会为空的论点。
专门创建代码的 null 保护和非 null 保护变体,而不是始终防止 null 有什么好处?这需要更多的努力,您可能会选择错误的选项;有什么好处?没有什么。
因此,如果故意忽略 null 保护没有任何好处,为什么还要弄清楚是否有必要防止 null 呢?只包含空保护比花时间弄清楚在这种特殊情况下是否可能不需要空保护更容易。
另请注意,您具体指的是在线演示代码或 Resharper 生成的模板,在这两种情况下,它们都旨在覆盖广泛的受众并保持广泛适用。
推荐阅读
- python-2.7 - 错误:__init__() 有一个意外的关键字参数“n_splits”
- symfony4 - Symfony 4 的 laupiFrpar/LopiPusherBundle 配置
- c# - Discord.Net bot 在服务器上托管时出现奇怪的延迟
- amazon-web-services - AWS:向 RDS 和 EC2 实例添加正确的入站安全组
- google-apps-script - 无法运行教程脚本
- android - 如何更改活动当服务器中的标志发生变化时,应用程序应该每 30 秒检查一次服务器#android?
- batch-file - 控制某个 MP 对象在播放音频文件时更改音量设置
- kdb - 向表中添加“求和”行
- java - JavaFX | IntelliJ 理念| ImageView 不显示 SceneBuilder 中显示的图像,它是预览
- javascript - Javascript:forEach 函数更改数据