2010-01-13 6 views
5

En el ejemplo siguiente, ¿será destruido (eliminado) el pen devuelto o no?uso de 'using' en .NET

' VB' 
Public Function GetPen() As System.Drawing.Pen 
    Using pen As New System.Drawing.Pen(_Color, _Width) 
    pen.DashStyle = _DashStyle 
    Return pen 
    End Using 
End Function 

// C# 
public System.Drawing.Pen GetPen() 
{ 
    using (System.Drawing.Pen pen = new System.Drawing.Pen(_Color, _Width)) 
    { 
     pen.DashStyle = _DashStyle; 
     return pen; 
    } 
} 

[EDIT]

Sólo una precisión más ... es el objeto de la pluma enviada a la persona que llama de GetPen por referencia o 'clonado' como una estructura? Lo sé, esto es una clase, pero con objetos GDI nunca estoy seguro ...

¿será destruida (dispuesto) la pen creados en GetPen() cuando el método externo dispondrá su pen obtuvieron con GetPen()?

+1

¿Qué encontró que sucedió cuando lo intentaste? – Lazarus

+0

@Lazarus: No lo intenté aún cuando pregunté. Pregunté primero: D – serhio

+0

después de las pruebas: Obtuve un null (Nada) no válido (con parámetros no válidos) pluma ... – serhio

Respuesta

3

Sí, el bolígrafo se desechará. Sin embargo, es realmente una mala idea; ¡devuelve una pluma que ya está dispuesta!

Lo que quiere hacer es eliminar la instrucción Using de GetPen. La declaración Usando debe ser utilizado por las personas que llaman GetPen:

Using pen As Pen = GetPen() 
    ''// Draw with this pen 
End Using 

O en C#:

using(Pen pen = GetPen()) 
{ 
    // Draw with this pen 
} 

[EDIT]

Sí, una referencia se devuelve al método de llamada, no se una copia. Es por eso que si desecha el lápiz en GetPen, no puede usar ese lápiz en el método de llamada ;-)

Debido a que GetPen y el método de llamada apuntan al mismo objeto Pen, solo necesita llame a Dispose en el método de llamada.

7

Sí, se desechará. Luego lo está devolviendo en un estado de eliminación, por lo que no servirá para nada. Si desea utilizar un método de fábrica como este para devolver una instancia de Pen, tendrá que encargarse de tirarlo externamente al método, sin utilizar un bloque using dentro del método de esta manera.

+3

aún puede usar usando: 'using (Pen p = GetAPen()) {...}' – tster

6

La pluma no será necesariamente recogida de basura, pero tendrá su método Dispose() llamado.

1

Sí, se desechará.

1

Se eliminará automáticamente cuando se realice el retorno. El uso de forzar el uso de Dispose() implícitamente

3

El bolígrafo se eliminará antes de devolverlo. Es el equivalente de

public System.Drawing.Pen GetPen() 
{ 
    try 
    { 
     System.Drawing.Pen pen = new System.Drawing.Pen(_Color, _Width); 

     pen.DashStyle = _DashStyle; 
    } 
    finally 
    { 
     pen.Dispose(); 
    } 
    return pen; 

} 
+1

grita 'System.Drawing.Pen pen' fuera Try Catch block :) – serhio

+0

No estoy exactamente seguro de eso ... La definición de la variable está dentro de la instrucción using, por lo que depende de la implementación del compilador (que no estoy familiarizado con) puede estar dentro o fuera. Puedo ver cómo puede estar afuera (evitando un NRE en el bloque finally). – Will

0

Su objeto Pen estará dispuesto antes del retorno completa y se le dejó con un objeto pluma en un estado no válido.

1

Sí.

El objeto Pen devuelto se Disposed antes de que el llamador lo reciba.

En los métodos de estilo Get(), no desea tratar con la eliminación de objetos.Permita que la persona que llama Descarte del objeto DESPUÉS de ya terminaron. Esperaría que la función de llamada se viera así:

using(Pen myPen = GetPen()) 
{ 
    // My code here. 
} 
0

Sí. En las versiones C# y VB.net de su código, se llama al método .Dispose() antes de que la función regrese. Eso no es lo mismo que destruirlo (el objeto aún existe), pero para todos los propósitos prácticos el objeto es inútil, porque el recurso no administrado que lo hizo interesante y útil ahora se ha liberado.

El patrón correcto para utilizar en la construcción de un recurso IDisposable dentro de una función es simplemente devolverlo, y utilizan una declaración using a llamar a la función, así:

public System.Drawing.Pen GetPen() 
{ 
    var pen = new System.Drawing.Pen(_Color, _Width)) 
    pen.DashStyle = _DashStyle; 
    return pen; 
} 

public void FunctionThatCallsGetPen() 
{ 
    using (System.Drawing.Pen pen = GetPen()) 
    { 
     //use pen here 
    } 
} 
0

usando es igual a la siguiente declaración más o menos:

tratar {

 var something = new something() ; 

}

finalmente {

if (something != null) 
{ something.Dispose();} 

}

1

el código necesita ser estructurado de manera diferente porque usted está volviendo un objeto que está dispuesta inmediatamente después de.

public System.Drawing.Pen GetPen() 
{ 
    System.Drawing.Pen pen = new System.Drawing.Pen(_Color, _Width) 
    { 
     DashStyle = _DashStyle; 
    } 
    return pen; 
} 

Entonces llaman usando:

using (System.Drawing.Pen pen = GetPen()) 
{ 
    //Do stuff with your pen... 
}