2009-09-28 11 views
5

Se voglio restringere la portata di una variabile in C#, posso introdurre sostegni supplementari - vale a dire:Campo di applicazione e come restringere 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; } 

    } 
} 

nell'IDE, non posso più fare riferimento y al di fuori dello scopo introdotto dalle nuove parentesi graffe. Avrei pensato che ciò significherebbe che la variabile y sarebbe disponibile per la garbage collection.

(è interessante notare che quando la visualizzazione del codice compilato usando riflettore sembra che non v'è alcuna differenza con o senza i tiranti supplementari)

Esiste un modo simile a questo per restringere portata utilizzando VB. netto? Questo ha un impatto su quando le variabili definite nello scope interno possono essere spazzate via?

risposta

0

In C# almeno, non fa alcuna differenza per la garbage collection quando un debugger non è collegato - il GC è in grado di funzionare quando una variabile viene letta l'ultima volta, e una variabile non conta come un Radice GC dopo quel punto. Ad esempio:

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"); 

(in termini di terminologia, la variabile stessa non sono raccolte, è solo che mentre conta come "root" al garbage collector, esso impedisce l'oggetto si riferisce a di essere raccolte .)

Quando hai un debugger collegato, il GC è molto più conservativo, poiché potresti voler esaminare il valore di una variabile dopo il suo ultimo punto di lettura "normale".

Il principale vantaggio di ridurre l'ambito è la chiarezza, IMO. Se una variabile ha un ambito ristretto, puoi dimenticartene quando non stai guardando quel pezzetto di codice (supponendo che non sia catturato da un delegato, ecc.).

Non so se VB ha un equivalente di un blocco di istruzioni per nessuna ragione diversa dall'ambito dell'ambito; l'equivalente più vicino può essere una dichiarazione With ... o una dichiarazione Do ... Loop While False, nessuna delle quali è del tutto soddisfacente.

+0

per quanto riguarda l'ambito. L'aiuto .Net cita il blocco Con come definizione di un livello di blocco di ambito e si applica a qualsiasi cosa definita all'interno del blocco, ma non al soggetto del blocco. portata restringimento potrebbe essere ottenuto utilizzando Con 1 end con o Con Vero End With ma si sente ancora hacky ... – hitch

+0

Il comportamento GC è la stessa in VB.NET. VB.NET non ha alcun equivalente di un blocco di istruzioni solo per la portata - si veda la voce MSDN (dalla risposta di paintballbob) http://msdn.microsoft.com/en-us/library/1t0wsc67.aspx – MarkJ

2

non sembra essere un buon modo per creare un nuovo scope in vb, ma puoi creare un ciclo che viene eseguito solo una volta garantito e quindi dichiarare la tua variabile all'interno di quel ciclo.

MSDN ebbe a dire circa la durata di una variabile:

Anche se la portata di una variabile è limitata ad un blocco, la sua durata è ancora quella di tutta la procedura. Se si inserisce il blocco più di una volta durante la procedura, ciascuna variabile di blocco mantiene il valore precedente. Per evitare risultati imprevisti in questo caso, è consigliabile inizializzare le variabili di blocco all'inizio del blocco.

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

sembra che le variabili sono soggetti soltanto alla raccolta dei rifiuti una volta che la procedura è terminata, ma anche allora il garbage collector non verrà eseguito a meno che il mucchio è sempre affollato. Molto probabilmente per le piccole app non viene mai raccolto nulla prima che l'app venga chiusa.

+0

Lei ha ragione circa la portata e la durata. Non del tutto corretto sulla raccolta dei dati inutili solo dopo che la procedura è terminata. Può succedere prima, vedi la risposta di Skeet. – MarkJ

5

È interessante notare che lo sviluppatoreFusion C# -vb.convertitore di codice netto converte

{ 
    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 

come senso di limitare l'ambito. Sono sorpreso che dà fastidio tenendo conto paintballbob's answer

0

Perché non basta creare un paio di metodi? Un ambito deve essere definito in un metodo. Una volta che esci dal metodo, lasci l'ambito: pulito e facile. Il modo in cui stai facendo è molto poco ortodosso - ti suggerirei di attenersi alle convenzioni e usare i metodi se sei preoccupato per il creep dell'ambito (cosa stai descrivendo).

Problemi correlati