Wie Sie "richtig" implementieren von Dispose() (nach FxCop), wenn Ihre Umsetzung ist eine leere Methode? (CA1063)

Habe ich eine Implementierung von einem interface, und das interface erweitert IDisposable. In meinem konkreten Implementierung der Schnittstelle, brauche ich nicht entsorgen alles, so dass ich nur eine leere Dispose() Methode.

public interface IMyStuff : IDisposable
{
}

public MyStuffImpl : IMyStuff
{
    public void Dispose()
    {
    }
}

Nun in FxCop, diese Ergebnisse in einem CA1063:

Error, Certainty 95, for ImplementIDisposableCorrectly
{
    Resolution   : "Provide an overridable implementation of Dispose(
                   bool) on 'MyStuffImpl' or mark the type as sealed. 
                   A call to Dispose(false) should only clean up native 
                   resources. A call to Dispose(true) should clean up 
                   both managed and native resources."
}
CriticalWarning, Certainty 75, for CallGCSuppressFinalizeCorrectly
{
    Resolution   : "Change 'MyStuffImpl.Dispose()' to call 'GC.SuppressFinalize(
                   object)'. This will prevent derived types that introduce 
                   a finalizer from needing to re-implement 'IDisposable' 
                   to call it."
}
Error, Certainty 95, for ImplementIDisposableCorrectly
{
    Resolution   : "Modify 'MyStuffImpl.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."
}

So, wie es aussieht kann ich dies beheben, in eine von 2 Möglichkeiten:


Machen die Klasse sealed:

public sealed MyStuffImpl : IMyStuff
{
    public void Dispose()
    {
    }
}

Implementieren, die Teil der typischen Muster:

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

    private void Dispose(bool disposing)
    {
    }
}

In meinem Fall, ich Plane nicht, auf die Umsetzung dieser immer wieder erweitert, also werde ich wohl lösen, indem es den sealed, aber ich gebe zu, ich weiß wirklich nicht verstehen, warum es wichtig ist, wenn es versiegelt ist oder nicht.

Auch, nur weil meine Klasse ist versiegelt, FxCop nicht mehr, erzählt mir, dass Dispose() rufen sollte GC.SupressFinalize(this); aber ist das wirklich wahr? Ist es "besser" in .NET nur immer rufen SupressFinalize Dispose unabhängig?

  • Vielleicht ist dein interface IDisposable nicht implementieren sollte wenn Sie Dinge haben, die Umsetzung Ihrer Schnittstelle, die nicht brauchen, entsorgen. Implementieren Sie IDisposable neben Ihre Schnittstelle als notwendig.
  • OP ist die Umsetzung eine andere Schnittstelle IDisposable erbt. IEnumerator<T> ist ein Beispiel.
  • Wenn die meisten Implementierungen sind Einweg, diese Schnittstelle sollte auch werden, um Anwender zu ermuntern, von der Schnittstelle zu verfügen richtig.
  • Ich weiß nicht, was FxCop ist zu tun, aber ich möchte darauf hinweisen, dass Ihre Klasse acutually fehlt der finalizer. So SuppressFinalize nichts.
  • Wenn eine Fabrik geht zurück Dinge, die möglicherweise oder möglicherweise nicht IDisposable, der return-Typ von der Fabrik sollte man IDisposable. Dies ist der Grund IEnumerator<T> implementiert IDisposable - es ist der Rückgabetyp einer factory-Methode.
  • Ja, nicht, dass es wirklich wichtig ist, aber in meiner realen Anwendung, die die Instanz ist dependency injiziert, und einige Implementierungen brauchen, zu entsorgen.

Schreibe einen Kommentar