2009-09-28 9 views
5

Si deseo de reducir el alcance de una variable en C#, puedo introducir apoyos adicionales - es decir:Ámbito de aplicación y cómo reducir usando VB.Net

class Program 
{ 
    static void Main(string[] args) 
    { 
     myClass x = new myClass(); 
     x.MyProperty = 1000; 
     Console.WriteLine("x = " + x.MyProperty); 

     { 
      myClass y = new myClass(); 
      y.MyProperty = 2000; 
      Console.WriteLine("y = " + y.MyProperty); 
     } 

     myClass y2 = new myClass(); 
     y2.MyProperty = 3000; 
     Console.WriteLine("y2 = " + y2.MyProperty); 

    } 

    class myClass 
    { 

     public int MyProperty { get; set; } 

    } 
} 

en el IDE, ya no puedo de referencia Y fuera del alcance introducido por los nuevos refuerzos. Pensé que esto significaría que la variable y estaría disponible para la recolección de basura.

(es interesante observar que cuando se ve el código compilado usando reflector parece que no hay ninguna diferencia con o sin los apoyos adicionales)

¿Hay alguna manera similar a este para acotar el alcance al utilizar VB. ¿red? ¿Esto tiene algún impacto cuando las variables definidas en el alcance interno pueden ser basura?

Respuesta

0

En C# al menos, no hace ninguna diferencia en la recolección de basura cuando no hay un depurador conectado - el GC puede funcionar cuando se lee por última vez una variable, y una variable no cuenta como una Raíz de GC después de ese punto Por ejemplo:

object y = new object(); 
Console.WriteLine("y is still a GC root"); 
Console.WriteLine(y); 
Console.WriteLine("y is not a GC root now"); 
y = null; 
Console.WriteLine("y is still not a GC root"); 

(En cuanto a la terminología, la propia variable no se recoge, es sólo que, si bien se cuenta como una "raíz" para el recolector de basura, que impide que el objeto que se está refiriendo a de ser recogido .)

Cuando tiene un depurador conectado, el GC es mucho más conservador, ya que es posible que desee examinar el valor de una variable después de su último punto de lectura "normal".

La principal ventaja de reducir el alcance es la claridad, IMO. Si una variable tiene un alcance reducido, puede olvidarse de ella cuando no está mirando ese bit de código (suponiendo que no sea capturado por un delegado, etc.).

No sé si VB tiene el equivalente de un bloque de instrucciones sin otro motivo que el alcance; el equivalente más cercano puede ser una declaración With ... o una declaración Do ... Loop While False, ninguna de las cuales es del todo satisfactoria.

+0

en lo que respecta al alcance, la ayuda de .Net menciona que el bloque define un nivel de alcance de bloque, y se aplica a cualquier cosa definida dentro del bloque, pero no al sujeto del bloque. alcance estrechamiento podría lograrse mediante el uso de Con 1 extremo con o con verdadera Fin Con pero todavía se siente hacky ... – hitch

+0

El comportamiento GC es el mismo en VB.NET. VB.NET no tiene equivalente de un bloque de instrucciones solo para el alcance: consulte la entrada de MSDN (desde la respuesta de paintballbob) http://msdn.microsoft.com/en-us/library/1t0wsc67.aspx – MarkJ

2

no parece haber una buena forma de crear un nuevo ámbito en vb, pero puede crear un bucle que se ejecute solo una vez garantizado y luego declarar su variable dentro de ese bucle.

MSDN tenía esto que decir acerca de la vida de una variable:

Aunque el alcance de una variable está limitada a un bloque, su tiempo de vida sigue siendo la de todo el procedimiento. Si ingresa al bloque más de una vez durante el procedimiento, cada variable de bloque conserva su valor anterior. Para evitar resultados inesperados en tal caso, es aconsejable inicializar las variables de bloque al comienzo del bloque.

src: http://msdn.microsoft.com/en-us/library/1t0wsc67.aspx

parece que las variables sólo están sujetos a la recolección de basura una vez que el procedimiento ha terminado, pero incluso entonces el recolector de basura no se ejecutará a menos que la pila se está llenando. Lo más probable es que para aplicaciones pequeñas nunca se obtenga basura hasta que se cierre la aplicación.

+0

Tiene razón sobre el alcance y la duración. No es del todo correcto que la recolección de basura solo suceda una vez que el procedimiento haya finalizado. Puede suceder antes, ver la respuesta de Skeet. – MarkJ

5

Curiosamente, el developerFusion C# -vb.convertidor de código de red convierte

{ 
    myClass y = new myClass(); 
    y.MyProperty = 2000; 
    Console.WriteLine("y = " + y.MyProperty); 
} 

a

If True Then 
    Dim y As New [myClass]() 
    y.MyProperty = 2000 
    Console.WriteLine("y = " & y.MyProperty) 
End If 

como una manera de limitar el alcance. Me sorprende que le moleste tener en cuenta paintballbob's answer

0

¿Por qué no crear algunos métodos? Un alcance debe ser definido en un método. Una vez que sale del método, abandona el alcance, limpio y fácil. La forma en que lo está haciendo es muy poco ortodoxa: le sugiero que se adhiera a los métodos de convención y uso si está preocupado por el alcance del alcance (lo que está describiendo).

Cuestiones relacionadas