private void Dispose(bool)?

Nat*_*ond 5 c# code-analysis fxcop idisposable

在一些地方,人们建议使用private void Dispose(bool)IDisposable模式.这似乎过时了(至少对于未密封的类),因为新建议的模式(根据微软)protected virtual void Dispose(bool).

The thing is, Code Analysis does not report private void Dispose(bool) for violating CA1063, even though it seems to violate the pattern directly.

What's up with this? Is private void Dispose(bool) somehow getting called (or compiled to something that looks like protected virtual Dispose(bool)?

If this is some issue with Code Analysis and is the incorrect pattern, are there ways to detect this? Possibly with StyleCop?

Edit: After consideration, is it that a base class can call base.Dispose() which will hit private void Dispose(bool)? Even if it isn't able to pass in an argument?

Edit: Sample

public class A : IDisposable
{
    ~A()
    {
        this.Dispose(false);
    }

    public void Dispose()
    {
        this.Dispose(true);
        GC.SuppressFinalize(this);
    }

    private void Dispose(bool disposing) // Should be protected virtual void Dispose(bool)
    {
        Console.WriteLine("A");
    }
}

public class B : A
{
    protected virtual void Dispose(bool disposing) // Proper pattern.
    {
        Console.WriteLine("B");
    }
}

public static class Program
{
    static void Main(string[] args)
    {
        A a = new A();
        a.Dispose(); // Prints "A"

        B b = new B();
        b.Dispose(); // Prints "A"!
    }
}
Run Code Online (Sandbox Code Playgroud)

As you can see from this, it makes using the dispose pattern totally unwieldy.

You can get around this a bit by hiding the public void Dispose(void) and then calling base.Dispose() somewhere. This then works 'similar' to the proper dispose pattern when calling B b = new B(); b.dispose(); except when calling A b = new B(); b.Dispose();, which only calls A's Dispose method.

public class B : A
{
    public void Dispose() // Causes CA error with or without "new".
    {
        this.Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing) // Proper pattern.
    {
        base.Dispose(); // Writes "A" (without quotes).
        Console.WriteLine("B");
    }
}
Run Code Online (Sandbox Code Playgroud)

Basically, this whole thing seems terrible. Do we know if it is a bug that CA accepts private void Dispose(bool) and is there a way to at least throw a warning with StyleCop?

Edit: I don't think I should accept Alexandre's answer, as relative to the question I have it basically boils down to "Could be a bug", along with something that should be a comment. If anyone else has something more conclusive, I think that would be a more appropriate answer.

Ale*_*ela 6

实现Dispose方法

所述IDisposable的接口需要一个实施单参数方法,处置.但是,dispose模式需要实现 两个Dispose方法:

  • 公共非虚拟(在Visual Basic中为NonInheritable)IDisposable.Dispose实现,没有参数.
  • 受保护的虚拟(在Visual Basic中为Overridable)Dispose方法.

因为公共的,非虚拟的(NonInheritable in Visual Basic),无参数的Dispose方法是由该类型的使用者调用的,其目的是释放非托管资源并指示终结器(如果存在)不必跑.因此,它有一个标准的实现:

public void Dispose()
{
   // Dispose of unmanaged resources.
   Dispose (true);
   // Suppress finalization.
   GC.SuppressFinalize (this);
}
Run Code Online (Sandbox Code Playgroud)

在第二个重载中,disposing参数是一个布尔值,指示方法调用是来自Dispose方法(其值为true)还是来自终结器(其值为false).

当垃圾收集器决定不再需要你的对象时,它会尝试最终确定它,以防你忘记调用无参数的dispose方法,因为如果你这样做并且你正在遵循模式,那么调用将被抑制.

请参阅:最终确定的工作原理

私有与受保护的虚拟:

如果您想要支持正确遵循模式的子类,则应始终使用受保护的虚拟文件.

为什么有些人使用私人版本?也许是因为继承从来就不是他们的意图,特别是如果你只是使用像Resharper这样的工具动态生成方法,大多数时候这些方法都是私有的.

为什么代码分析不报告问题?

可能是一个错误.提供一个小样本来解决问题,以便其他人可以在他们的机器上进行测试.