C# VB.Net的作用域及其缩小方法
如果我想缩小C#中变量的范围,我可以引入额外的大括号-即:C# VB.Net的作用域及其缩小方法,c#,vb.net,scope,reflector,C#,Vb.net,Scope,Reflector,如果我想缩小C#中变量的范围,我可以引入额外的大括号-即: class Program { static void Main(string[] args) { myClass x = new myClass(); x.MyProperty = 1000; Console.WriteLine("x = " + x.MyProperty); { myClass y = new myClass()
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可以用于垃圾收集
(值得注意的是,当使用reflector查看编译后的代码时,使用或不使用附加大括号似乎没有区别)
在使用VB.net时,有没有类似的方法来缩小范围?这对内部作用域中定义的变量何时可以被垃圾收集有任何影响吗?在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会更加保守,因为您可能希望在最后一个“正常”读取点之后检查变量的值
在我看来,减少作用域的主要好处是清晰。如果变量的作用域很窄,那么当你不看那一段代码时,你可以忘记它(假设它没有被委托等捕获)
我不知道VB是否有任何等价于语句块的东西,除了作用域之外没有其他原因;最接近的等价物可能是带有语句的
。。。或者一个Do
循环而False语句,两者都不完全令人满意。在vb中创建新作用域似乎不是一个好方法,但您可以创建一个只运行一次的循环,然后在该循环中声明变量
MSDN对变量的生存期有这样的说法:
即使变量的范围仅限于一个块,其生存期仍然是整个过程的生存期。如果在过程中多次输入块,每个块变量将保留其以前的值。为了避免在这种情况下出现意外结果,最好在块的开头初始化块变量
src:
似乎只有在过程完成后,变量才会进行垃圾收集,但即使如此,除非堆变得拥挤,否则垃圾收集器也不会运行。对于小型应用程序来说,最有可能的情况是,在关闭应用程序之前,没有任何东西会被垃圾收集。有趣的是,developerFusion c#-vb.net代码转换器会转换
{
myClass y = new myClass();
y.MyProperty = 2000;
Console.WriteLine("y = " + y.MyProperty);
}
到
作为限制范围的一种方式。我很惊讶它会让人费心记住为什么不创建一些方法呢?应该在方法中定义范围。一旦你退出这个方法,你就离开了这个范围——干净而简单。您这样做的方式非常非正统-如果您担心范围爬行(您正在描述的内容),我建议您坚持惯例并使用方法。关于范围,.Net帮助提到with块定义了范围的块级别,它适用于块内定义的任何内容,但不适用于块的主题。通过使用With 1 end With或With True end With可以缩小范围,但它仍然感觉很粗糙…在VB.NET中GC行为是相同的。VB.NET没有等效的语句块,只是用于作用域-请参阅MSDN条目(来自paintballbob的回答),您对作用域和生存期的看法是正确的。关于垃圾收集只在过程完成后发生的说法不太正确。这可能发生得更早,见Skeet的答案。
If True Then
Dim y As New [myClass]()
y.MyProperty = 2000
Console.WriteLine("y = " & y.MyProperty)
End If