Ho un'implementazione di un'interfaccia e quell'interfaccia estende IDisposable
. Nella mia particolare implementazione dell'interfaccia, non ho bisogno di gettare nulla, quindi ho solo un metodo vuoto Dispose()
.Come si "implementa" correttamente Dispose() (secondo FxCop) quando l'implementazione è un metodo vuoto? (CA1063)
public interface IMyStuff : IDisposable
{
}
public MyStuffImpl : IMyStuff
{
public void Dispose()
{
}
}
Ora, in FxCop, questo si traduce in un 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."
}
Così, sembra che posso risolvere questo in uno dei 2 modi:
rendere la classe sealed
:
public sealed MyStuffImpl : IMyStuff
{
public void Dispose()
{
}
}
attuare parte del modello tipico:
public MyStuffImpl : IMyStuff
{
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool disposing)
{
}
}
Nel mio caso, non ho intenzione su questa implementazione mai in fase di estensione, quindi io probabilmente risolverlo rendendola sealed
, ma ammetto Non capisco davvero perché è importante se è sigillato o meno.
Inoltre, solo perché la mia classe è sigillata, FxCop non mi dice più che Dispose()
dovrebbe chiamare GC.SupressFinalize(this);
ma è proprio vero? È "migliore" in .NET chiamare sempre SupressFinalize in Dispose, indipendentemente?
Forse la tua interfaccia non dovrebbe implementare IDisposable se hai cose che implementano la tua interfaccia che non hanno bisogno di smaltimento. Puoi implementare IDisposable * in aggiunta * alla tua interfaccia, se necessario. –
@DBM OP sta implementando un'altra interfaccia che eredita IDisposable. 'IEnumerator' è un esempio. –
phoog
@DBM: Se la maggior parte delle implementazioni è disponibile, questa interfaccia dovrebbe essere anche, per incoraggiare gli utenti dell'interfaccia a disporre correttamente. – SLaks