简体   繁体   English

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

[英]Scope and how to narrow it using VB.Net

If I want to narrow scope of a variable in C#, I can introduce additional braces - ie: 如果我想在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; }

    }
}

In the ide, I can no longer reference y outside of the scope introduced by the new braces. 在ide中,我不能再在新大括号引入的范围之外引用y。 I would have thought that this would mean that the variable y would be available for garbage collection. 我原以为这意味着变量y可用于垃圾收集。

(it is interesting to note that when viewing the compiled code using reflector it appears that there is no difference with or without the additional braces) (有趣的是,当使用反射器查看编译后的代码时,无论是否有额外的大括号,都没有区别)

Is there any way similar to this to narrow scope when using VB.net? 使用VB.net时是否有类似的方法缩小范围? Does this have any impact on when variables defined in the inner scope may be garbage collected? 这对内部作用域中定义的变量何时可能被垃圾收集有影响吗?

Interestingly, the developerFusion c#-vb.net code converter converts 有趣的是,developerFusion c#-vb.net代码转换器转换

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

to

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

as a way of limiting the scope. 作为限制范围的一种方式。 I'm surprised it bothers bearing in mind paintballbob's answer 我很惊讶它记住了paintballbob的答案

there doesn't seem to be a good way to create a new scope in vb, but you can make a loop that runs only once guaranteed and then declare your variable inside that loop. 似乎没有一种在vb中创建新作用域的好方法,但是你可以创建一个只运行一次的循环,然后在该循​​环中声明你的变量。

MSDN had this to say about the lifetime of a variable: MSDN有关于变量生命周期的说法:

Even if the scope of a variable is limited to a block, its lifetime is still that of the entire procedure. 即使变量的范围仅限于块,其寿命仍然是整个过程的寿命。 If you enter the block more than once during the procedure, each block variable retains its previous value. 如果在过程中多次输入块,则每个块变量将保留其先前的值。 To avoid unexpected results in such a case, it is wise to initialize block variables at the beginning of the block. 为避免在这种情况下出现意外结果,最好在块的开头初始化块变量。

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

it seems that the variables are only subject to garbage collection once the procedure has finished, but even then the garbage collector will not run unless the heap is getting crowded. 似乎变量只在程序完成后才进行垃圾收集,但即使这样,垃圾收集器也不会运行,除非堆变得拥挤。 Most likely for small apps nothing ever gets garbage collected until the app is closed. 最有可能的小应用程序,在应用程序关闭之前,什么都不会被垃圾收集。

Why not just create a few methods? 为什么不创建一些方法呢? A scope should be defined in a method. 范围应该在方法中定义。 Once you exit the method you leave the scope - clean and easy. 退出方法后,您将离开示波器 - 干净简单。 The way you are doing is very unorthodox - I would suggest you stick to convention and use methods if you are worried about scope creep (what you are describing). 你正在做的事情是非常不正统的 - 如果你担心范围蔓延(你所描述的),我建议你坚持使用约定并使用方法。

In C# at least, it doesn't make any difference to garbage collection when a debugger isn't attached - the GC is able to work out when a variable is last read, and a variable doesn't count as a GC root after that point. 至少在C#中,当没有附加调试器时,它对垃圾收集没有任何影响 - 当上次读取变量时,GC能够计算出来,并且在此之后变量不计入GC根目录点。 For example: 例如:

 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 terms of terminology, the variable itself isn't collected, it's just that while it counts as a "root" to the garbage collector, it prevents the object it's referring to from being collected.) (就术语而言,变量本身并未被收集,只是当它被视为垃圾收集器的“根”时,它会阻止它所引用的对象被收集。)

When you've got a debugger attached, the GC is much more conservative, as you may want to examine a variable's value after its last "normal" read point. 当您连接了调试器时,GC更加保守,因为您可能希望在其最后一个“正常”读取点之后检查变量的值。

The major benefit to reducing scoping is clarity, IMO. 减少范围界定的主要好处是清晰度,IMO。 If a variable has a narrow scope, you can forget about it when you're not looking at that bit of code (assuming it's not captured by a delegate etc). 如果变量具有较窄的范围,那么当您不查看该位代码时(假设代理不会捕获它等),您可以忘记它。

I don't know whether VB has any equivalent of a statement block for no reason other than scoping; 我不知道除了作用域之外,VB是否有任何等价的语句块; the nearest equivalent may be a With statement... or a Do ... Loop While False statement, neither of which is entirely satisfactory. 最近的等价物可能是一个With语句......或者一个Do ... Loop While False语句,两者都不完全令人满意。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM