这真的是一种改进(当内部范围处于循环中时,将var移动到内部范围)?

时间:2012-12-17 21:47:57

标签: c# refactoring resharper scope

Resharper推荐这些变种:

List<string> senderDeviceIDList;
string senderDeviceID;
. . .
            foreach (var item in PlatypiIds)
            {
                senderDeviceIDList = await GetSenderDeviceIDForSenderID(item);
                senderDeviceID = senderDeviceIDList[0];

...可以在内部范围内声明,如下所示:

    foreach (var item in PlatypiIds)
    {
        List<string> senderDeviceIDList = await GetSenderDeviceIDForSenderID(item);
        string senderDeviceID = senderDeviceIDList[0];

......但是真的更好吗&#34;?不会导致变量被声明N次(每个foreach循环一次)?

4 个答案:

答案 0 :(得分:30)

此处的性能或内存分配没有任何好处,因为if中的 oustside 中的变量顺便提一下,范围在IL中声明。

唯一的好处是变量范围的本地化。将它移动到使用它的范围,这带来了好处:

  • 轻松重构(可能是最重要的)

  • 可读性。如果你在范围内看到变量,你知道它在该范围内只使用了 ,如果你看到一些显然不在里面的变量,你知道改变它会影响代码的其他部分。所以改变它会引入一些潜在的危险。

简而言之,它是关于您正在编写的代码的可读性和可用性,并不会带来任何性能或内存消耗优势。

答案 1 :(得分:9)

  

这不会导致vars被声明N次(每个foreach循环一次)吗?

逻辑上,从概念的角度来看,是,这就是重点!从逻辑上讲,它们每个循环存在一次,并且在循环范围之外没有任何意义。

作为实现细节,不,它不会导致创建多个局部变量。该方法只有一个变量,它将在一般情况下重新使用(当它被允许时)。有一些例外情况,例如当您使用匿名方法关闭变量时,它无法重复使用变量。

请注意,因为C#强制您在使用它们之前初始化所有局部变量,运行时甚至不负责在每次循环后清除它,编译器不会让您重新使用之前的垃圾(除非你在循环开始时将它显式初始化为默认值。)

答案 2 :(得分:2)

无论如何,每次迭代都要为这些对象分配一次实例,在初始方法中唯一不同的是你要声明一次引用,而不是像第二个例子那样每次迭代。

如果你需要在foreach循环结束时使用这些对象的最终状态(毛状),那么你可能想要采用第一种方法。

答案 3 :(得分:0)

有时候存在利益。

如果得到的数组很大,那么将它移到内部范围 - 即。减少范围和生命周期 - 可能会阻止它转移到以后的垃圾收集代,并且会在有形延迟的情况下进行垃圾收集。