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

问题描述 投票:22回答:4

Resharper推荐这些vars:

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

......但那真的“更好”吗?这不会导致变量被声明N次(每个foreach循环一次)?

c# refactoring resharper scope
4个回答
30
投票

这里在性能或内存分配方面没有任何好处,顺便说一句,if范围内或外部的变量在IL中声明。

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

  • 容易重构(可能是最重要的)
  • 可读性。如果你在范围内看到变量,你知道它只在该范围内使用,如果你看到一些显然不在里面的变量,你知道改变它会影响代码的其他部分。所以改变它会带来一些潜在的危险。

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


9
投票

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

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

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

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


2
投票

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

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


0
投票

有时候存在利益。

如果产生的数组是巨大的,那么将它移动到内部范围 - 即。减少范围和生命周期 - 可能会阻止它转移到以后的垃圾收集代,并且有可能延迟收集垃圾。

© www.soinside.com 2019 - 2024. All rights reserved.