【发布时间】:2015-02-12 00:27:20
【问题描述】:
最近我发现你可以在 C# 中做到这一点:
{
// google
string url = "#";
if ( value > 5 )
url = "http://google.com";
menu.Add( new MenuItem(url) );
}
{
// cheese
string url = "#"; // url has to be redefined again,
// so it can't accidently leak into the new menu item
if ( value > 45 )
url = "http://cheese.com";
menu.Add( new MenuItem(url) );
}
而不是即:
string url = "#";
// google
if ( value > 5 )
url = "http://google.com";
menu.Add( new MenuItem(url) );
// cheese
url = "#"; // now I need to remember to reset the url
if ( value > 45 )
url = "http://cheese.com";
menu.Add( new MenuItem(url) );
这可能是一个不好的例子,可以通过许多其他方式解决。
“没有声明的范围”功能是否有任何模式是一种好的做法?
【问题讨论】:
-
起初感觉像这样使用范围很有用,因为这意味着您可以使用相同的变量名和其他范围相关的活动。然而,实际上,应该避免过度嵌套,因为它会损害可读性,如果您能够像这样分离出范围,那么您可能应该将代码重构为单独的方法。
-
我倾向于喜欢单独的方法,纯粹是因为它可以重复使用。
-
我相信您所写的是“裸块”的一个完全有效的用例。当然,如果你连续有很多这样的块,你应该考虑将每个块的公共部分重构为一个新方法,但有时你真的只需要连续两次做几乎但不完全相同的事情.
-
@rhughes 范围界定不会影响 GC 的回收规则,除非附加了调试器。如果未附加调试器,则变量在方法中最后一次使用后有资格回收(并且在方法之外没有引用)。
-
@rhughes 不,你不正确。如果您有 100 行代码并且对象是最后一次从第 2 行读取的,则 GC 可以在第 3 行收集并释放该对象的内存,即使该变量在另外 97 行中没有“超出范围”(这只适用于当您没有附加调试器时)