提问人:HonanLi 提问时间:2/23/2022 最后编辑:Lance U. MatthewsHonanLi 更新时间:2/23/2022 访问量:81
为什么退出“using”会调用意外的Dispose()?
Why exiting "using" invokes unexpected Dispose()?
问:
这是我的情况:
class A : IDisposable
{
public void Dispose() { Console.WriteLine("A Dispose"); }
}
class B : A
{
public new void Dispose(){ Console.WriteLine("B Dispose"); }
}
class Program
{
static void Main(string[] args)
{
using (B b = new B())
{
}
}
}
最终输出为“A Dispose”。 我读过一些文档,其中介绍了覆盖和新的区别,并且告诉人们“使用”实质上等于“尝试最终”。但是我仍然无法回答为什么它不是自动调用的 B::D ispose。 比较下面的输出是“B Dispose”
B b = new B();
try
{
}
finally
{
b.Dispose();
}
请帮忙,我错过了。
答:
2赞
Etienne de Martel
2/23/2022
#1
根据 C# 语言规范,对于引用类型:
using (ResourceType resource = «expression» ) «statement»
相当于
{
ResourceType resource = «expression»;
try {
«statement»;
}
finally {
IDisposable d = (IDisposable)resource;
if (d != null) d.Dispose();
}
}
正如你所看到的,资源首先被强制转换为 ,这意味着 ' 是被调用的资源,因为 只是隐藏它而不是覆盖它。IDisposable
A
Dispose
B
Dispose
如果要在类层次结构中正确实现,请参阅文档中的最佳实践。IDisposable
评论
0赞
Etienne de Martel
2/23/2022
如果 finally 的实现是 简单而不是 ,那么 就是被调用的那个,因为它隐藏了 的 。这不是这里发生的事情,OP在问为什么。resource.Dispose()
((IDisposable)resource).Dispose()
B
Dispose
A
Dispose
0赞
Etienne de Martel
2/23/2022
啊,很公平。我会澄清这部分。
评论
new
override
B
IDisposable.Dispose
new
new void IDisposable.Dispose(){ Console.WriteLine("B Dispose"); }
new
本质上是“我想重用我的基类使用过的名称”。如果您为该方法使用了任何其他名称,则不必使用,而且更明显的是,它与同名基类的方法无关。new