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 manIDisposable
. Dies ist der GrundIEnumerator<T>
implementiertIDisposable
- 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.
Du musst angemeldet sein, um einen Kommentar abzugeben.
SuppressFinalize()
ist bedeutungslos, es sei denn, die Instanz hat einen finalizer.Wenn Ihre Klasse nicht mit einem finalizer, aber nicht
sealed
sollten Sie nochSuppressFinalize
im Fall einer geerbten Klasse fügt ein finalizer.Beide Möglichkeiten sind richtig, außer dass
Dispose(bool)
werden mussprotected virtual
.Dispose(bool)
überlastung ist nicht überschreibbare. +1 für den Hinweis dassSuppressFinalize
ist es sinnlos, auf Objekte ohne finalizer.Dispose()
. (obwohl ich nicht sicher bin, warum es nicht nennenSupressFinalize()
imDispose(true)
)In Ihrem "implementieren, die Teil der typischen Muster" - option, sollten Sie Ihre
Dispose(bool)
Methodeprotected virtual
:Dass Unterklassen eine Gelegenheit zur Verarbeitung Entsorgung aller Ressourcen, die Sie verwalten. Das ist die Bedeutung von "kann" in "Bieten eine überschreibbare Implementierung von Dispose(bool)"
Natürlich
public virtual
würde auch genügen FxCop.