2009-09-28 25 views
5

如果我想縮小在C#的可變範圍縮小,我可以引入額外的括號 - 即:範圍和如何使用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; } 

    } 
} 

在IDE中,我不能再參考座標y超出了新大括號引入的範圍。我原以爲這意味着變量y可用於垃圾收集。

(有趣的是,注意,當使用反射鏡觀看經編譯的代碼時,似乎沒有任何區別有或沒有附加的括號)

是否有與此類似用VB時,以縮小範圍的任何方式。淨?這對內部作用域中定義的變量何時可能被垃圾收集有影響嗎?

回答

0

至少在C#中,當沒有附加調試器時,垃圾收集沒有任何區別 - 當上次讀取一個變量時,GC可以計算出來,並且變量不會計爲GC之後的根。例如:

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

(在術語方面,變量本身是不收集,它只是,雖然它計數作爲「根」至垃圾收集器,其防止它從被收集參照對象。)

當你有一個調試器連接時,GC更保守,因爲你可能想要在最後一個「正常」讀取點後檢查一個變量的值。

減少範圍界定的主要好處是清晰度,IMO。如果一個變量的範圍很窄,那麼當你不看這段代碼時(假設它沒有被委託人捕獲),你可以忘掉它。

我不知道除了作用域外,VB是否有任何等價的語句塊,最近的等價物可能是With聲明...或Do ... Loop While False聲明,兩者都不完全令人滿意。

+0

關於範圍.Net幫助提到With塊定義了作用域的塊級別,它適用於塊內定義的任何內容,但不適用於塊的主題。縮小範圍可以通過使用 與 或 與真正 結束,而實現與1 結束與 但它仍然感覺哈克... – hitch 2009-09-28 06:20:17

+0

的GC行爲是在VB.NET相同。 VB.NET沒有等效於僅用於範圍的語句塊 - 請參閱MSDN條目(來自paintballbob的答案)http://msdn.microsoft.com/en-us/library/1t0wsc67.aspx – MarkJ 2009-09-28 11:21:31

2

在vb中似乎沒有創建新範圍的好方法,但是您可以創建一個只保證運行一次的循環,然後在該循​​環內聲明您的變量。

MSDN是這樣說的一個變量的生存期:

即使變量的範圍被限制在一個塊時,其壽命仍是整個過程的。如果在該過程中多次輸入該塊,則每個塊變量將保留其先前的值。爲了避免在這種情況下出現意外結果,在塊的開始處初始化塊變量是明智的。

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

似乎變量僅須遵守垃圾收集一旦程序已經完成,但即使如此,垃圾收集器將不會運行,除非堆越來越擁擠。最有可能的小應用程序沒有收到垃圾直到應用程序關閉。

+0

您對範圍和生命週期是正確的。只有在程序結束後纔會發生垃圾收集,這是不太正確的。它可以發生得更早,參見Skeet的答案。 – MarkJ 2009-09-28 11:19:57

5

有趣的是,developerFusion c#-vb。淨代碼轉換器轉換

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

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

爲限制範圍的一種方式。我很驚訝它銘記在心paintballbob's answer

0

爲什麼不只是創建幾個方法?範圍應該在方法中定義。一旦你退出方法,你就離開了範圍 - 乾淨而簡單。你做的方式非常非正統 - 如果你擔心範圍蔓延(你在描述什麼),我建議你堅持使用慣例並使用方法。