The Framework Design Guidelines (2nd Ed., page 327) say:
CONSIDER providing method
Close()
, in addition to theDispose()
, if close is standard terminology in the area.When doing so, it is important that you make the Close implementation identical to
Dispose
and consider implementingIDisposable.Dispose
method explicitly.
So, following the provided example, I've got this class:
public class SomeClass : IDisposable {
private SomeDisposable someInnerDisposable;
public void Open() {
this.someInnerDisposable = new SomeDisposable();
}
void IDisposable.Dispose() {
this.Close();
}
public void Close() {
this.Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing) {
if (disposing) {
this.someInnerDisposable.Dispose();
this.someInnerDisposable = null;
}
}
}
FxCop doesn't seem to like that:
CA1816 : Microsoft.Usage : 'SomeClass.Close()' calls 'GC.SuppressFinalize(object)', a method that is typically only called within an implementation of 'IDisposable.Dispose'. Refer to the IDisposable pattern for more information.
CA1816 : Microsoft.Usage : Change 'SomeClass.IDisposable.Dispose()' to call 'GC.SuppressFinalize(object)'. This will prevent unnecessary finalization of the object once it has been disposed and it has fallen out of scope.
CA1063 : Microsoft.Design : Modify 'SomeClass.IDisposable.Dispose()' so that it calls Dispose(true), then calls GC.SuppressFinalize on the current object instance ('this' or 'Me' in Visual Basic), and then returns.
CA1063 : Microsoft.Design : Rename 'SomeClass.IDisposable.Dispose()' to 'Dispose' and ensure that it is declared as public and sealed.
-or-
I tried
[SuppressMessage("Microsoft.Design", "CA1063:ImplementIDisposableCorrectly",
Justification = "Framework Design Guidelines say it's ok.")]
void IDisposable.Dispose()
{
this.Close();
}
but FxCop 1.36 still reports them.
EDIT: Changing it around as suggested eliminates all but this warning:
CA1063 : Microsoft.Design : Rename 'SomeClass.IDisposable.Dispose()' to 'Dispose' and ensure that it is declared as public and sealed.
EDIT 2: CODE_ANALYSIS was indeed missing. Thanks.
Implement the dispose pattern for a derived class Instead, to clean up a derived class, you provide the following: A protected override void Dispose(bool) method that overrides the base class method and performs the actual cleanup of the derived class. This method must also call the base. Dispose(bool) ( MyBase.
If the class inherits from a class that implements IDisposable it must call the Dispose(), or Dispose(bool) method of the base class from within its own implementation of Dispose() or Dispose(bool), respectively. This ensures that all resources from the base class are properly released.
Dispose should call GC. SuppressFinalize so the garbage collector doesn't call the finalizer of the object. To prevent derived types with finalizers from having to reimplement IDisposable and to call it, unsealed types without finalizers should still call GC.
public void Dispose() { Dispose(disposing: true); // This object will be cleaned up by the Dispose method. // Therefore, you should call GC. SuppressFinalize to // take this object off the finalization queue // and prevent finalization code for this object // from executing a second time.
Change it around.
Have Close() call this.Dispose() and put the logic in the Dispose() method instead of the Close() method.
------------------- Further info after edit ---------------
Also, changing the declaration to:
public void Dispose()
should get rid of the other error. Since you have it declared as:
void IDisposable.Dispose()
It's not marked as public and sealed, and FxCop complains. Personally, I prefer to get avoid the errors instead of suppressing them.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With