范围以及如何使用VB.Net缩小范围

hit*_*tch 5 c# vb.net reflector scope

如果我想在C#中缩小变量的范围,我可以引入额外的括号 - 即:

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; }

    }
}
Run Code Online (Sandbox Code Playgroud)

在ide中,我不能再在新大括号引入的范围之外引用y.我原以为这意味着变量y可用于垃圾收集.

(有趣的是,当使用反射器查看编译后的代码时,无论是否有额外的大括号,都没有区别)

使用VB.net时是否有类似的方法缩小范围?这对内部作用域中定义的变量何时可能被垃圾收集有影响吗?

Rob*_*obS 6

有趣的是,developerFusion c#-vb.net代码转换器转换

 {
    myClass y = new myClass();
    y.MyProperty = 2000;
    Console.WriteLine("y = " + y.MyProperty);
 }
Run Code Online (Sandbox Code Playgroud)

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

作为限制范围的一种方式.我很惊讶它记住了paintballbob的答案


Jon*_*eet 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");
Run Code Online (Sandbox Code Playgroud)

(就术语而言,变量本身不会被收集,只是虽然它被视为垃圾收集器的“根”,但它会阻止收集它所引用的对象。)

当您附加了调试器时,GC 会更加保守,因为您可能希望在最后一个“正常”读取点之后检查变量的值。

在我看来,缩小范围的主要好处是清晰。如果变量的作用域很窄,那么当您不查看那段代码时(假设它没有被委托等捕获),您可以忘记它。

我不知道 VB 是否有任何相当于语句块的东西,除了范围之外没有其他原因;最接近的等价物可能是一个With陈述……或一个Do……Loop While False陈述,两者都不是完全令人满意的。