2011-09-15 16 views
9

decir que tengo el siguiente:IDisposable Pregunta

public abstract class ControlLimitBase : IDisposable 
{ 
} 

public abstract class UpperAlarmLimit : ControlLimitBase 
{ 
} 

public class CdsUpperAlarmLimit : UpperAlarmLimit 
{ 
} 

dos preguntas:

1. Estoy un poco confundido cuando los miembros de mi IDisposable realidad conseguirían llamada. ¿Serán llamados cuando una instancia de CdsUpperAlarmLimit salga del alcance?

2. ¿Cómo manejaría la eliminación de los objetos creados en la clase CdsUpperAlarmLimit? ¿Esto también debería derivarse de IDisposable?

Respuesta

22

Dispose() nunca se llama automáticamente, depende de cómo se usa realmente el código.

1.) Dispose() se llama cuando se llama específicamente Dispose():

myAlarm.Dispose(); 

2.) Dispose() se llama al final de un bloque using usando una instancia de su tipo.

using(var myAlarm = new CdsUpperAlarmLimit()) 
{ 

} 

El bloque using es el azúcar sintáctica para un bloque try/finally con una llamada a Dispose() en el objeto "que se utiliza" en el bloque finally.

+0

Perdona mi ignorancia aquí.Escribí una clase que implementa 'IDisposable', y cuando lo uso en un bloque' using', nunca se llama al método 'Dispose()'. ¿Eso significa que todavía necesito llamar a 'Dispose()' dentro de mi bloque 'using'? – jp2code

+0

@jpcode: no, no es necesario - el bloque 'using' es equivalente a' try/finally' con una llamada 'Dispose' en el bloque de código' finally' – BrokenGlass

0

cuando se utiliza un objeto IDisposable, siempre es bueno para usarlo de esta manera:

using(var disposable = new DisposableObject()) 
{ 
    // do you stuff with disposable 
} 

Después de que el bloque usando ha sido ejecutado, el método Dispose se llama en el objeto IDisposable. De lo contrario, necesitarás llamar a Dispose manualmente.

3

Estoy un poco confundido sobre cuándo se llamaría a mis miembros IDisposable. ¿Serán llamados cuando una instancia de CdsUpperAlarmLimit salga del alcance?

No. Su ser llamado cuando se utiliza using construcción como:

using(var inst = new CdsUpperAlarmLimit()) 
{ 
    //... 
}//<-------- here inst.Dispose() gets called. 

Pero no se consiga llamar si se escribe esto:

{ 
    var inst = new CdsUpperAlarmLimit(); 
    //... 
}//<-------- here inst.Dispose() does NOT get called. 

Sin embargo, puede escribir esto también:

var inst = new CdsUpperAlarmLimit(); 
using(inst) 
{ 
    //... 
}//<-------- here inst.Dispose() gets called. 
0
  1. Cuando alguien llama al .Dispose en él.
  2. No, ya lo implementa a través de la herencia.
3

IDisposable tiene un miembro, Dispose().

Esto se invoca cuando elige llamarlo. Lo más típico es que lo haga por usted el marco con el azúcar sintáctico de bloque using.

5
  1. No, IDisposable no se llamará solo de forma automática. Más le normalmente llamada Dispose con una declaración using, así:

    using (ControlLimitBase limit = new UpperAlarmLimit()) 
    { 
        // Code using the limit 
    } 
    

    Esto es efectivamente un try/finally bloque, por lo que se llamará Disposeembargo que dejar el bloque.

  2. CdsUpperAlarmLimit ya implementa IDisposable indirectamente. Si sigue el normal pattern for implementing IDisposable in non-sealed classes, anulará void Dispose(bool disposing) y desechará sus recursos compuestos allí.

Tenga en cuenta que el recolector de basura no hace llamada Dispose sí mismo - aunque puede llamar a un finalizador . Sin embargo, rara vez debe utilizar un finalizador a menos que tenga un identificador directo en recursos no administrados.

Para ser honesto, por lo general encuentro que vale la pena intentar cambiar el diseño para evitar tener que mantener recursos no administrados en las clases: implementar IDisposable correctamente en el caso general es francamente un problema. No es tan malo si su clase está sellada (no es necesario el método adicional, simplemente implemente el método Dispose()), pero aún significa que sus clientes deben conocerla, para que puedan usar una declaración using apropiada.

0

IDisposable se implementa cuando desea indicar que su recurso tiene dependencias que deben ser descargadas y limpiadas explícitamente. Como tal, IDisposable nunca se llama automáticamente (como con la recolección de basura).

En general, para manejar IDisposables, se debe envolver su uso en un bloque using

using(var x = new CdsUpperAlarmLimit()) { ... } 

esta compila a:

CdsUpperAlarmLimit x = null; 
try 
{ 
    x = new CdsUpperAlarmLimit(); 
    ... 
} 
finally 
{ 
    x.Dispose(); 
} 

Así que, volviendo a tema, si su tipo, CdsUpperAlarmLimit, es implementar IDisposable, le dice al mundo: "Tengo cosas que deben ser eliminadas". Las razones más comunes para esto sería:

  • CdsUpperAlarmLimit mantiene algunos otros recursos IDisposable (como FileStreams, ObjectContexts, temporizadores, etc.) y cuando se hace CdsUpperAlarmLimit siendo utilizado, tiene que asegurarse de que el FileStreams, ObjectContexts, temporizadores, etc. también obtienen el llamado Dispose.
  • CdsUpperAlarmLimit está utilizando recursos no administrados o memoria y se debe limpiar cuando se hace o no habrá fuga de una memoria
Cuestiones relacionadas