2009-09-28 40 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

为什么不只是创建几个方法?范围应该在方法中定义。一旦你退出方法,你就离开了范围 - 干净而简单。你做的方式非常非正统 - 如果你担心范围蔓延(你在描述什么),我建议你坚持使用惯例并使用方法。