|
|
1
347
这不仅是美学 ,但也减少了 maximum nesting level 在方法内部。这通常被认为是一个优点,因为它使方法更容易理解(事实上, many static analysis tools 提供对此的度量作为代码质量的指标之一)。 另一方面,它也使你的方法有多个退出点,而另一组人认为这是不允许的。 就个人而言,我同意ReSharper和第一组(在一种有例外的语言中,我发现讨论“多个退出点”是愚蠢的;几乎任何东西都可以抛出,所以所有方法中都有许多潜在的退出点)。 关于性能 :两个版本 本应 在每种语言中都是等效的(如果不是在IL级别,那么肯定是在代码抖动结束之后)。理论上,这取决于编译器,但实际上,当今任何广泛使用的编译器都能够处理比这更高级的代码优化情况。 |
|
|
2
320
方法中间的返回并不一定是坏的。如果能使代码的意图更清晰,最好立即返回。例如:
在这种情况下,如果
我从 refactoring catalog 。这种特定的重构称为:用保护子句替换嵌套条件语句。 |
|
3
104
这有点宗教色彩,但我同意ReSharper的观点,即你应该更喜欢少筑巢。我认为这超过了函数有多个返回路径的负面影响。 减少嵌套的关键原因是为了提高 代码可读性和可维护性 请记住,许多其他开发人员将来需要阅读您的代码,缩进较少的代码通常更容易阅读。 前提条件 是一个很好的例子,说明在函数开始时提前返回是可以的。为什么函数其余部分的可读性会受到前置条件检查的影响? 至于从一个方法返回多次的负面影响,调试器现在非常强大,很容易准确地找出特定函数返回的位置和时间。 函数中有多个返回值不会影响维护程序员的工作。 代码可读性差。 |
|
|
4
70
正如其他人所提到的,不应该影响性能,但还有其他考虑因素。除了这些合理的担忧之外,在某些情况下,这也会让你陷入困境。假设你正在处理一个
对比一下 看似 等效反演:
因此,在某些情况下,似乎是正确倒置的
|
|
|
5
54
只在函数结束时返回的想法来自语言支持异常之前的日子。它使程序能够依赖于将清理代码放在方法末尾,然后确保它会被调用,并且其他程序员不会在方法中隐藏导致跳过清理代码的返回。跳过清理代码可能会导致内存或资源泄漏。 然而,在支持例外的语言中,它不提供这样的保证。在支持异常的语言中,执行任何语句或表达式都可能导致控制流,从而导致方法结束。这意味着必须通过使用finally或使用关键字来进行清理。 不管怎样,我认为很多人引用“方法末尾唯一返回”的指导方针,而不理解为什么这是一件好事,减少嵌套以提高可读性可能是一个更好的目标。 |
|
6
34
我想补充一点,那些倒置的if是有名字的——保护条款。只要有可能,我就用它。 我讨厌在一开始就有if的地方阅读代码,只有两个屏幕的代码,没有其他屏幕。只需反转if并返回。这样就没有人会浪费时间滚动。 |
|
|
7
22
它不仅影响美观,还可以防止代码嵌套。 它实际上可以作为确保数据有效的前提条件。 |
|
|
8
18
这当然是主观的,但我认为它在两点上有了很大的改善:
|
|
|
9
15
多个返回点在C中是一个问题(在较小程度上是C++),因为它们迫使你在每个返回点之前复制清理代码。通过垃圾回收
归根结底,这取决于你和你的同事觉得什么更容易阅读。 |
|
|
10
12
保护条款或先决条件(如您可能看到的)检查是否满足某个条件,然后中断程序的运行。它们非常适合那些你只对一个结果感兴趣的地方
您反转条件,如果满足反转条件,则中断
您将看到在嵌套条件下应用此功能的最佳示例:
vs:
你会发现很少有人认为第一种更干净,但当然,这完全是主观的。一些程序员喜欢通过缩进来了解某个东西在什么条件下运行,而我更愿意保持方法流的线性。 我一点也不建议预编码会改变你的生活或让你上床,但你可能会发现你的代码更容易阅读。 |
|
|
11
12
在性能方面,这两种方法之间没有明显的区别。 但编码不仅仅是性能。清晰度和可维护性也很重要。而且,在这种不影响性能的情况下,这是唯一重要的事情。 对于哪种方法更可取,存在相互竞争的思想流派。 一种观点是其他人提到的观点:第二种方法降低了嵌套级别,从而提高了代码的清晰度。这在命令式风格中是很自然的:当你没有什么可做的时候,你最好早点回来。 从功能性风格的角度来看,另一种观点是一个方法应该只有一个出口点。函数式语言中的一切都是表达式。因此,if语句必须始终包含else子句。否则if表达式并不总是有值。因此,在功能风格中,第一种方法更自然。 |
|
|
12
9
这里有几个好点,但有多个回报点 可能无法阅读 如果方法很长。也就是说,如果你要使用多个返回点,只要确保你的方法很短,否则多个返回点将失去可读性。 |
|
13
9
性能分为两部分。当软件在生产环境中时,您有性能,但您也希望在开发和调试时有性能。开发人员最不希望的就是“等待”一些琐碎的事情。最后,在启用优化的情况下编译它将产生类似的代码。所以很高兴知道这些小技巧在这两种情况下都有回报。
问题中的情况很明显,ReSharper是正确的。而不是筑巢
|
|
|
14
7
就我个人而言,我更喜欢只有一个出口点。如果你保持你的方法简短扼要,这很容易实现,而且它为下一个处理你代码的人提供了一个可预测的模式。 如。
如果你只是想在函数退出之前检查函数内某些局部变量的值,这也是非常有用的。你所需要做的就是在最终返回上放置一个断点,你保证会命中它(除非抛出异常)。 |
|
|
15
6
避免多个出口点 能 从而提高性能。我对C#不太确定,但在C++中,命名返回值优化(Copy Elision,ISO C++'03 12.8/15)取决于是否有一个出口点。这种优化避免了复制构造返回值(在您的特定示例中,这并不重要)。这可能会在紧循环中带来可观的性能提升,因为每次调用函数时都会保存构造函数和析构函数。
但对于99%的情况,保存额外的构造函数和析构函数调用不值得失去嵌套的可读性
|
|
|
16
5
有很多很好的理由 代码的外观 但是呢 结果 ? 让我们来看看一些C#代码及其IL编译形式:
这个简单的代码片段可以编译。您可以打开生成的
生成的IL代码执行以下操作:
因此,代码似乎会跳到末尾。如果我们用嵌套代码做一个普通的if怎么办?
IL指令中的结果非常相似。不同之处在于,之前每个条件都有两次跳跃:如果
不管怎样,程序计数器总是会跳起来。 |
|
|
17
4
理论上,反转
更多关于分支预测的信息 here . |
|
|
18
4
这完全是有争议的。在提前返回的问题上没有“程序员之间的共识”。据我所知,这总是主观的。 可以进行性能论证,因为最好写下条件,这样它们最常为真;也可以说,它更清晰。另一方面,它确实创建了嵌套测试。 我认为你不会得到这个问题的确切答案。 |
|
|
19
3
这里已经有很多有见地的答案了,但我还是想指出一个稍微不同的情况:与其先决条件,不如把它放在函数之上——事实上,想想一个循序渐进的初始化过程,你必须检查每一步是否成功,然后继续下一步。在这种情况下,您无法检查顶部的所有内容。 当我使用Steinberg的ASIOSDK编写ASIO主机应用程序时,我发现我的代码真的很难阅读,因为我遵循了嵌套范式。它有八层深,我看不出有任何设计缺陷,正如Andrew Bullock上面提到的那样。当然,我本可以将一些内部代码打包到另一个函数中,然后将剩余的级别嵌套在那里,使其更具可读性,但这对我来说似乎相当随机。 通过用保护子句替换嵌套,我甚至发现了我对清理代码的一部分的误解,这部分代码本应在函数中更早发生,而不是在末尾。使用嵌套分支,我永远不会看到这种情况,你甚至可以说它们导致了我的误解。 因此,这可能是另一种情况,在这种情况下,倒排ifs可以使代码更清晰。 |
|
|
20
2
这是一个意见问题。 我的正常方法是避免单行if,并在方法的中间返回。 你不希望在你的方法中到处都有像它所暗示的那样的行,但有一点值得一提的是,要检查方法顶部的一堆假设,只有当它们都通过时,才能进行实际工作。 |
|
|
21
2
在我看来,如果你只是返回void(或者一些你永远不会检查的无用返回代码),提前返回是可以的,这可能会提高可读性,因为你避免了嵌套,同时你明确表示你的函数已经完成。 如果你真的要返回一个returnValue,嵌套通常是一种更好的方法,因为你只在一个地方返回returnValue(在末尾-duh),这可能会使你的代码在很多情况下更易于维护。 |
|
|
22
1
我不确定,但我认为,R#试图避免远跳。当你有IF-ELSE时,编译器会做这样的事情: 条件为false->远跳到false条件标签 true_condition_label: 说明1 ... 说明_n false条件标签: 说明1 ... 说明_n 端块 若条件为真,则没有跳转,也没有卷展L1缓存,但跳转到false_condition_label可能很远,处理器必须卷展自己的缓存。同步缓存的成本很高。R#尝试将远跳转替换为短跳转,在这种情况下,所有指令都已在缓存中的可能性更大。 |
|
|
23
0
我认为这取决于你更喜欢什么,正如前文所述,似乎没有普遍的共识。 为了减少烦恼,您可以将这种警告减少为“提示” |
|
|
24
0
我的想法是,“函数中间”的返回不应该如此“主观”。 原因很简单,以这段代码为例: function do_something( data ){
if (!is_valid_data( data ))
return false;
do_something_that_take_an_hour( data );
istance = new object_with_very_painful_constructor( data );
if ( istance is not valid ) {
error_message( );
return ;
}
connect_to_database ( );
get_some_other_data( );
return;
}
也许第一次“回归”不是那么直观,但这真的很省钱。 关于干净代码的“想法”太多了,只需要更多的练习就可以摆脱“主观”的坏想法。 |
|
|
25
0
这种编码有几个优点,但对我来说,最大的好处是,如果你能快速返回,你可以提高应用程序的速度。IE我知道,由于前提条件X,我可以快速返回错误。这首先消除了错误情况,降低了代码的复杂性。在很多情况下,由于cpu管道现在可以更干净,它可以阻止管道崩溃或切换。其次,如果你处于循环中,快速中断或退出可以为你节省大量的cpu。一些程序员使用循环不变量来实现这种快速退出,但在这种情况下,你可能会破坏你的cpu管道,甚至造成内存查找问题,这意味着cpu需要从外部缓存加载。但基本上,我认为你应该做你想做的事情,即结束循环或函数,而不是仅仅为了实现正确代码的抽象概念而创建复杂的代码路径。如果你唯一的工具是锤子,那么一切看起来都像钉子。 |
|
|
A B · C#Excel自动调整列避免长文本时出错 1 年前 |
|
|
Megrez7 · C#ToArray转换合并为一行,导致数组元素更改 1 年前 |
|
Aycon · 在工厂方法中释放部分创建的对象的正确方法是什么? 1 年前 |
|
|
Sei · Avalonia/WPF将路由器传递到控制模板 1 年前 |