鉴于以下类实现了Dispose
和IDisposable.Dispose
:
internal class DisposableClass : IDisposable
{
public void Dispose()
{
}
void IDisposable.Dispose()
{
}
}
当我调用DisposeableClass.Dispose(通过类的实例)时,调用public void Dispose
:
DisposableClass newClass = new DisposableClass();
try
{
}
finally
{
newClass.Dispose();
}
如果将try-finally更改为using语句,则调用IDisposable.Dispose。
using (DisposableClass newClass = new DisposableClass())
{
}
但是NOT the IDisposable.Dispose which I defined
。
编译器将using语句转换为((IDisposable)newClass).Dispose()
。完整的方法名称显示它来自System.IDisposable.Dispose。
IL_0014: callvirt instance void [mscorlib]System.IDisposable::Dispose()
何时会调用IDisposable.Dispose的自定义实现?
请注意,我没有使用这个实际的实现,我知道不应该使用它。但我仍然很好奇在什么时候调用哪个实现。
如果我对每个Dispose方法都有不同的实现方式;什么时候会调用哪个实现?
答案 0 :(得分:3)
您的处置方法是错误的。您应该查看The Dispose Pattern以了解如何正确执行此操作。
然而...... 要回答你的问题,他们如何/为何被称为......
当您说public void Dispose()
时,newClass.Dispose();
被调用,因为它是最好的"匹配"对于你所问的。通过它(并且没有变得太复杂),这是因为它是层次结构中最高的,因此是编译器期望您的意思,因为它是最具体的。如果您还没有创建自己的,那么它将通过层次结构来查找Dispose
方法。
当您使用using
换行时,编译器会生成与此类似的代码:
DisposableClass newClass = new DisposableClass();
try
{
}
finally
{
((IDisposable)newClass).Dispose();
}
因此,这将明确调用IDiposable
版本。
<强>更新强>
下面的完整工作示例将提供此输出:
Manually calling newClass.Dispose();
public void Dispose() being called.
Now wrapped in using...
void IDisposable.Dispose() being called.
Manually calling IDisposable.Dispose();
void IDisposable.Dispose() being called.
完整的工作代码(将其粘贴到控制台应用程序并运行):
using System;
namespace zPlayGround
{
class Program
{
static void Main()
{
Console.WriteLine("Manually calling newClass.Dispose();");
var newClass = new DisposableClass();
try
{
}
finally
{
newClass.Dispose();
}
Console.WriteLine("Now wrapped in using...");
using (var usingClass = new DisposableClass())
{
}
Console.WriteLine("Manually calling IDisposable.Dispose();");
var demoClass = new DisposableClass();
try
{
}
finally
{
((IDisposable)newClass).Dispose();
}
Console.ReadKey();
}
}
internal class DisposableClass : IDisposable
{
public void Dispose()
{
Console.WriteLine("public void Dispose() being called.\r\n");
}
void IDisposable.Dispose()
{
Console.WriteLine("void IDisposable.Dispose() being called.\r\n");
}
}
}