我应该将变量声明为尽可能接近它们将被使用的范围吗?
Posted
技术标签:
【中文标题】我应该将变量声明为尽可能接近它们将被使用的范围吗?【英文标题】:Should I declare variables as close as possible to the scope where they will be used? 【发布时间】:2011-09-02 06:41:36 【问题描述】:ReSharper 通常会建议我这样做,我仍在寻找一个很好的理由说明为什么要这样做。
我唯一想到的是,将其声明为更接近将要使用的范围,可以避免在某些不需要的情况下初始化它(因为条件等)
与此相关的内容如下:
int temp;
foreach (var x in collection)
temp = x.GetValue();
//Do something with temp
真的不一样吗
foreach (var x in collection)
int temp = x.GetValue();
//...
我的意思是,第二个代码不是更昂贵,因为它每次都在分配内存吗?还是两者都一样?当然,循环结束后,在第二个代码中垃圾收集器会处理temp
变量,但不是在第一个...
【问题讨论】:
【参考方案1】:声明尽可能接近使用是一个可读性决定。您的示例没有显示它,但在较长的方法中,很难筛选代码以找到 temp 变量。
这也是重构的优势。声明更接近源代码会导致以后更容易重构。
【讨论】:
【参考方案2】:第二个例子的成本可以忽略不计。唯一的区别是在第一个示例中,temp
将在 for
循环范围之外可用,因此它的存在时间将比在 for
循环中声明它时长。
如果您在for
循环之外需要temp
,则不应在该循环之外声明它。正如其他人所说,可读性和风格在这里比性能和记忆力更重要。
【讨论】:
那么这两个代码之间没有任何性能差异吗? (它是一个int
,但它可能是一个更复杂的类,需要更多的内存空间......)
@Oscar - 除了最小的初始化成本之外,堆栈变量基本上是免费的。
编译器可能会将循环内声明的变量移到循环外,所以不,实际上没有任何性能差异。通过在需要它们的范围的开头声明它们,您可以获得可读性和可维护性。
@Oscar - 即使它是一个更复杂的对象,您所做的只是复制一个引用。费用不高。【参考方案3】:
我同意,如果您在使用它的范围内初始化一个变量,那么您就是在帮助 gc,但我认为真正的原因更多地与代码维护最佳实践有关。这是一种减少您或其他开发人员在数月(或数年)不查看特定块后返回代码的认知负担的方法。当然,IDE 可以帮助您发现事物,但您仍然必须跳“去定义”的舞蹈。
【讨论】:
同意。希望这将是最好的原因之一:)
我想澄清一下为什么它可以减轻认知负担,以防万一有人好奇。其他开发人员不必考虑temp
的其他用途。它有助于为该变量提供上下文。【参考方案4】:
我相信没有性能优势,但更多的是一种编码风格。它更多的 C 编程风格在作用域的开头声明它。这里有更多细节:Scope of variables in C#
【讨论】:
【参考方案5】:这是与可读性有关的个人风格偏好。
很少有语言/系统会对性能产生明显影响。
我尝试遵循这两条规则。
一个类的所有核心属性都应该在一个地方一起定义。例如如果您正在处理订单,则 orderno、customerno、金额、销售税等应紧密定义。
构成类内部机制一部分的所有技术属性,例如迭代器、标志、状态变量,都应根据其用法进行定义。
或者说另一种业务/外部类型数据都定义在一个地方,技术/内部数据定义接近使用。
【讨论】:
【参考方案6】:区别在于编码风格和不同编码标准具有完全相反的规则的争议之一。在 C++ 世界中冲突仍然最强烈,C 语言强制变量在作用域的开头声明,因此老前辈(如我自己)非常习惯于“查看函数的开头”来查找变量。
您最常看到的 C# 风格是变量在需要它们的时候就出现了。这种风格限制了变量的存在,并最大限度地减少了您可能意外地表示某些其他变量的可能性。我觉得它很容易阅读。
在现代 C# 时代,将变量声明放在第一个使用点与喜欢和讨厌的 var
功能结合使用显然是最有益的。使用var
并没有那么有用,除非您将它与允许编译器和读者推断变量类型的赋值一起使用。 var
功能鼓励在首次使用时声明。
我,我喜欢var
,所以你可以猜出我更喜欢哪种编码风格!
【讨论】:
【参考方案7】:我总是被教导在函数、类等的顶部声明变量。这样更容易阅读。
【讨论】:
你当时用的是什么语言?以上是关于我应该将变量声明为尽可能接近它们将被使用的范围吗?的主要内容,如果未能解决你的问题,请参考以下文章