Tengo una implementación de una interfaz, y esa interfaz se extiende a IDisposable
. En mi implementación particular de la interfaz, no necesito deshacerme de nada, así que solo tengo un método Dispose()
vacío.¿Cómo implementa "adecuadamente" Dispose() (según FxCop) cuando su implementación es un método vacío? (CA1063)
public interface IMyStuff : IDisposable
{
}
public MyStuffImpl : IMyStuff
{
public void Dispose()
{
}
}
Ahora en FxCop, esto se traduce en 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."
}
Por lo tanto, parece que puedo resolver esto de una de las 2 formas:
hacer que la clase sealed
:
public sealed MyStuffImpl : IMyStuff
{
public void Dispose()
{
}
}
aplicar la parte del patrón típico:
public MyStuffImpl : IMyStuff
{
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool disposing)
{
}
}
En mi caso, yo no pienso en esta aplicación cada vez está extendiendo, así que probablemente se resolverá por lo que es sealed
, pero admito Realmente no entiendo por qué importa si está sellado o no.
Además, solo porque mi clase está sellada, FxCop ya no me dice que Dispose()
debe llamar al GC.SupressFinalize(this);
, pero ¿es eso cierto? ¿Es "mejor" en .NET simplemente llamar a SupressFinalize en Dispose independientemente?
Quizás su interfaz no debería implementar IDisposable si tiene cosas que implementan su interfaz que no necesitan deshacerse. También puede implementar IDisposable * en su interfaz según sea necesario. –
@DBM OP implementa otra interfaz que hereda IDisposable. 'IEnumerator' es un ejemplo. –
phoog
@DBM: si la mayoría de las implementaciones son desechables, esta interfaz también debería ser para alentar a los usuarios de la interfaz a desechar correctamente. – SLaks