Private void Dispose (bool)?

In several places, people suggested using private void Dispose(bool) for the IDisposable template. This seems deprecated, though (at least for unsealed classes), since the new proposed template (according to Microsoft) is protected virtual void Dispose(bool) .

The fact is, Code Analysis does not report private void Dispose(bool) for violating CA1063 , although this apparently violates the pattern directly.

What's up with that? Is private void Dispose(bool) somehow invoked (or compiled for what looks like protected virtual Dispose(bool) ?

If this is some kind of problem with code analysis and is the wrong template, are there any ways to detect this? Perhaps with StyleCop?

Edit: after considering, can the base class call base.Dispose() , which will fall into private void Dispose(bool) ? Even if he cannot pass an argument?

Edit: Example

 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"! } } 

As you can see from this, this makes using the layout template completely cumbersome.

You can get around this a bit by hiding public void Dispose(void) , and then when calling base.Dispose() . Then it works similarly to the correct dispose pattern when calling B b = new B(); b.dispose(); B b = new B(); b.dispose(); , except when calling A b = new B(); b.Dispose(); A b = new B(); b.Dispose(); that only calls the A 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"); } } 

In principle, all this seems awful. Do we know if this is a mistake that CA accepts private void Dispose(bool) and is there a way to at least issue a warning using StyleCop?

Edit: I don’t think I should accept Alexander’s answer, since regarding the question that I have, it basically comes down to “There may be a mistake”, as well as something that should be a comment. If anyone else has something more convincing, I think that would be a more appropriate answer.

+5
source share
1 answer

Deployment Method Implementation

The IDisposable interface requires a single implementation with no parameters , Dispose. However, the dispose pattern requires two Dispose methods :

  • Public non-virtual (NonInheritable in Visual Basic) IDisposable. An implementation that has no parameters.
  • Protected virtual (Overridable in Visual Basic) Dispose method.

Since the public , non-virtual (NonInheritable in Visual Basic) method without Dispose parameters is invoked by a consumer of this type, its goal is to free up unmanaged resources and indicate that the finalizer, if present, should not be launched. Because of this, it has a standard implementation:

 public void Dispose() { // Dispose of unmanaged resources. Dispose (true); // Suppress finalization. GC.SuppressFinalize (this); } 

In the second overload, the disposing parameter is a boolean that indicates whether the method is called from the Dispose method (its value is true) or from the finalizer (its value is false) .

When the garbage collector decides that your object is no longer needed, it will try to complete it if you forget to call the method without parameters, because if you did this and you follow the pattern, the call will be suppressed.

See: How finalization works

Private vs Protected Virtual:

You should always use a protected virtual file, as the documentation says that if you want to support subclasses that follow the template correctly.

Why do some people use the closed version? Perhaps because inheritance was never their intention, especially if you simply generate methods on the fly using tools like Resharper, in most cases these methods will be private.

Why doesn't Code Analysis report a problem?

May be a mistake. Provide a small sample that gives the problem so that other people can test their cars.

+6
source

All Articles