2010-08-23 8 views

Respuesta

12

Si utiliza el using statement del tipo cerrado ya debe aplicar IDisposable de otro modo el compilador emitirá un error. Por lo tanto, considere la implementación de IDisposable como un requisito previo para su uso.

Si desea utilizar la instrucción using en su clase personalizada, debe implementar IDisposable para ello. Sin embargo, esto es un poco atrasado porque no tiene sentido hacerlo por el simple hecho de hacerlo. Solo si tiene algo que desechar como un recurso no administrado debería implementarlo.

// To implement it in C#: 
class MyClass : IDisposable { 

    // other members in you class 

    public void Dispose() { 
     // in its simplest form, but see MSDN documentation linked above 
    } 
} 

Esto le permite:

using (MyClass mc = new MyClass()) { 

    // do some stuff with the instance... 
    mc.DoThis(); //all fake method calls for example 
    mc.DoThat(); 

} // Here the .Dispose method will be automatically called. 

Efectivamente eso es lo mismo que escribir:

MyClass mc = new MyClass(); 
try { 
    // do some stuff with the instance... 
    mc.DoThis(); //all fake method calls for example 
    mc.DoThat(); 
} 
finally { // always runs 
    mc.Dispose(); // Manual call. 
} 
+0

¿Puedes mostrar un ejemplo de código, por favor? – Troy

+1

@Troy: Ejemplo agregado para resaltar la explicación. –

+2

En realidad, es un patrón bastante útil para cuando tienes un código "sandwich" que debe/debe ejecutar algunas cosas en una sección finally. Por ejemplo, un escenario común sería un cursor ocupado, los pasos son ... 1./Copie el cursor existente 2./coloque el cursor en el cursor de espera 3./en una sección final, copie el original. Con un uso y IDisposable, a continuación, podría escribir código usando algo así como (Busy.WaitCursor) {// Cuando WaitCursor es una propiedad estática que devuelve una instancia de ocupados los ejemplares y conjuntos constructor y el dispose() re- conjuntos. } –

5

Usted está confundiendo cosas. Solo puede usar la palabra clave "using" en algo que implementa IDisposable.

Editar: Si utiliza la palabra clave using, no tiene que invocar explicity Dispose, se llamará automáticamente al final del bloque using. Otros ya han publicado ejemplos de cómo la sentencia using se traduce en una declaración try - finally, con Dispose invocado dentro del bloque finally.

+0

Puede usar la palabra clave "usar" al leer datos de un conjunto de registros, ¿correcto? – Troy

+1

@Troy, sí, porque IDataReader implementa IDisposable. –

+0

Solo si lo que está envolviendo su conjunto de registros implementa IDisposable. Si se compila, implementa IDisposable .... –

2

Utilizando solo dispondrá de objetos desechables. Así que agrupar un bloque de uso alrededor de un objeto que no implementa IDisposable es bastante inútil de hecho causará un error de compilación.

http://msdn.microsoft.com/en-us/library/yh598w02.aspx

As a rule, when you use an IDisposable object, you should declare and instantiate it in a using statement. The using statement calls the Dispose method on the object in the correct way, and it also causes the object itself to go out of scope as soon as Dispose is called. Within the using block, the object is read-only and cannot be modified or reassigned.

The using statement ensures that Dispose is called even if an exception occurs while you are calling methods on the object. You can achieve the same result by putting the object inside a try block and then calling Dispose in a finally block; in fact, this is how the using statement is translated by the compiler.

+1

De hecho, es un error del compilador. – Timwi

12

No se puede tener uno sin el otro.

Cuando se escribe:

using(MyClass myObj = new MyClass()) 
{ 
    myObj.SomeMthod(...); 
} 

compilador generará algo como esto:

MyClass myObj = null; 
try 
{ 
    myObj = new MyClass(); 
    myObj.SomeMthod(...); 
} 
finally 
{ 
    if(myObj != null) 
    { 
     ((IDisposable)myObj).Dispose(); 
    } 
} 

Así como se puede ver, mientras que tener using palabra clave se asume/requiere que se implementa IDisposable.

+0

+1, pero no se supone, es obligatorio. El código del compilador que mostró aquí se exceptuaría con una excepción de conversión inválida si el tipo no implementó IDisposable. Esta es la razón por la cual el compilador evita que esto ocurra al dar un error de compilación que hace que IDisposable sea necesario, no asumido, para usar en un uso. –

+0

@Jimmy sí, tienes razón, diciendo que asumí que lo decía en serio. La respuesta esta actualizada. – Incognito

4

Sí, la palabra clave es el uso de azúcar sintáctico para este tipo de patrón ... (de MSDN)

Font font1 = new Font("Arial", 10.0f); 
    try 
    { 
    byte charset = font1.GdiCharSet; 
    } 
    finally 
    { 
    if (font1 != null) 
     ((IDisposable)font1).Dispose(); 
    } 

Editar: un ejemplo útil.

Cuando encuentre que está haciendo las cosas de una sección consistentemente por último, por ejemplo, restablecer un cursor de nuevo a su forma predeterminada después de haber puesto a un cursor de espera, esto es un candidato para este patrón ...

public class Busy : IDisposable 
    { 

    private Cursor _oldCursor; 

    private Busy() 
    { 
     _oldCursor = Cursor.Current; 
    } 

    public static Busy WaitCursor 
    { 
     get 
     { 
     Cursor.Current = Cursors.WaitCursor; 
     return new Busy(); 
     } 
    } 

    #region IDisposable Members 

    public void Dispose() 
    { 
     Cursor.Current = _oldCursor; 
    } 

    #endregion 
    } 

Llamado como ...

using(Busy.WaitCursor) 
{ 
    // some operation that needs a wait cursor. 
} 
1

El uso de palabras clave que ya pone en práctica, por lo que si se utiliza el uso de palabras clave, usted no tiene que invocar IDisposable

1

Debe implementar IDisposable utilizar usando. Si intenta utilizar el uso de() de un tipo que no implementa IDisposable se obtiene el siguiente error de compilación tiempo:

error CS1674: 'SomeType': type used in a using statement must be implicitly convertible to 'System.IDisposable' 
Cuestiones relacionadas