你喜欢那些让你把“then”放在“if”之前的语言吗?

时间:2010-04-30 05:40:38

标签: c# programming-languages

我今天正在阅读我的一些C#代码并找到了这一行:

if (ProgenyList.ItemContainerGenerator.Status != System.Windows.Controls.Primitives.GeneratorStatus.ContainersGenerated) return;

请注意,您可以在不滚动的情况下判断它是一个与ItemContainerGenerator.Status一起使用的“if”语句,但是如果“if”子句的计算结果为“true”,则无法轻易判断该方法将在此时返回

实际上我应该将“return”语句单独移动到一行,但是它让我想到了首先允许语句的“then”部分的语言。如果C#允许,可能如下所示:

return if (ProgenyList.ItemContainerGenerator.Status != System.Windows.Controls.Primitives.GeneratorStatus.ContainersGenerated);

这可能有点“争论”,但我想知道人们对这种结构的看法。它可能有助于使像上面这样的行更具可读性,但它也可能是灾难性的。想象一下这段代码:

return 3 if (x > y);

逻辑上我们只能返回x> y,因为没有“其他”,但是我的一部分看着那个并且认为,“如果x< = y,我们还会回来吗?如果是这样,我们又回来了什么?”

您如何看待“之前的if”结构?它是否以您选择的语言存在?你经常使用它吗? C#会从中受益吗?

15 个答案:

答案 0 :(得分:14)

让我们重新格式化一下,看看:

using System.Windows.Controls.Primitives;

...

if (ProgenyList.ItemContainerGenerator.Status != GeneratorStatus.ContainersGenerated)
{
    return;
}

现在看到返回声明有多难?不可否认,你仍然需要滚动查看整个条件,但是在IDE中你不必......部分原因是因为没有尝试将条件和结果放在同一条线上,并且应该到期到using指令。

现有C#语法的好处是文本顺序反映了执行顺序 - 如果你想知道会发生什么,你可以从上到下阅读代码。

就我个人而言,我不是“如果......返回”的粉丝 - 我宁愿重新格式化代码以提高可读性而不是改变顺序。

答案 1 :(得分:10)

我不喜欢这种邀请的含糊之处。请考虑以下代码:

doSomething(x)
if (x > y);
doSomethingElse(y);

它在做什么?是的,编译器可以解决这个问题,但对于程序员来说这看起来很混乱。

答案 2 :(得分:9)

是。 它读起来更好。 Ruby将其作为语法的一部分 - 术语为“statement modifiers

irb(main):001:0> puts "Yay Ruby!" if 2 == 2
Yay Ruby!
=> nil
irb(main):002:0> puts "Yay Ruby!" if 2 == 3
=> nil

要结束,我需要强调你需要“谨慎使用”。红宝石成语是用于单行的。它可能会被滥用 - 但我认为这属于负责任的发展领域 - 不要通过建立限制来保护穷人,从而限制更好的开发者。

答案 3 :(得分:4)

对我来说这看起来很难看。现有的语法要好得多。

if (x > y) return 3;

答案 4 :(得分:4)

我认为如果范围仅限于return语句,那可能就行了。正如我在评论中所说,想象一下如果允许

{
   doSomething();
   doSomethingElse();

   // 50 lines...

   lastThink();
} if (a < b);

但即使仅在return陈述中允许它也可能是一个滑坡。人们会问,“return x if (a);是允许的,为什么不能像doSomething() if (a);那样?”然后你就在下坡的路上:)

我知道其他语言确实可以逃脱它,但是C#的哲学更多的是让一个正确的方式 TM 变得容易,并且通常避免使用多种方法来做某事(尽管有例外) 。就我个人而言,我认为它的效果非常好,因为我可以查看其他人的代码,并且知道它与我编写的代码几乎相同。

答案 5 :(得分:3)

我认为

没有任何问题
return 3 if (x > y);

它可能会困扰你,因为你不习惯语法。能够说

也很好
return 3 unless y <= x

这是一个很好的语法选项,但我不认为c#需要它。

答案 6 :(得分:1)

我认为Larry Wall在将此功能引入Perl时非常聪明。这个想法是你想把最重要的部分放在容易看到的开头。如果你有一个简短的陈述(即不是复合陈述),你可以把它放在if / while /等之前。如果你有一个长(即复合)语句,它会在条件之后进行括号。

答案 7 :(得分:1)

我个人喜欢让我选择的语言。

也就是说,如果你重构和重新格式化,你使用什么样的风格可能无关紧要,因为它们同样可读:

using System.Windows.Controls.Primitives;

...
var isContainersGenerated = 
    ProgenyList.ItemContainerGenerator.Status == GeneratorStatus.ContainersGenerated;

if (!isContainersGenerated) return;
//alternatively

return if (!isContainersGenerated);

答案 8 :(得分:1)

有人担心阅读代码,您认为声明 稍后才能执行可能执行。

例如,如果你读“doSomething(x)”,你会想“好吧所以这会调用doSomething(x)”然后你读了之后的“if”并且必须意识到之前的调用是有条件的if语句。

当“if”首先出现时,您立即知道以下代码可能,并且可以将其视为

我们倾向于按顺序阅读,因此阅读并记住“以下可能发生的事情”比阅读更容易,然后实现您刚刚阅读的所有内容需要重新分析,并且您需要评估所有内容以查看是否在你的新if语句的范围内。

答案 9 :(得分:0)

Perl和Ruby都有这个,它工作正常。就个人而言,我想要向你投掷尽可能多的功能。我编写代码的选择越多,整体质量就越好,对吧? “适合工作的工具”以及所有这些。

但实际上,这是一个有争议的问题,因为在C#的生命周期中这样一个基本的添加已经很晚了。由于编译器代码的大小及其语法分析算法,我们正处于需要进行大量工作的任何次要语法更改的位置。对于一个新的添加甚至被认为它必须带来相当多的功能,这只是一种(不那么)不同的方式来说同样的事情。

答案 10 :(得分:0)

人类从头到尾阅读。在分析代码流时,由于需要额外的回溯,limits of the short term memory使得更难以阅读后缀条件。对于简短表达式,这可能不是问题,但对于较长的表达式,对于那些用他们正在阅读的语言不seasoned的用户来说,这会产生很大的开销。

答案 11 :(得分:0)

同意令人困惑,我以前从未听说过这种结构,所以我认为使用之前的正确方法如果必须始终包含其他结果,例如

return (x > y) ? 3 : null;

否则就没有必要使用像

这样的Imperative结构
return 3 if (x > y);
return 4 if (x = y);
return 5 if (x < y);

imho这有点奇怪,因为我不知道在哪里使用它......

答案 12 :(得分:0)

它就像很多东西一样,当你在一个有限的环境中使用它时,它是完全有意义的(一个衬垫),如果你在其他任何地方使用它就毫无意义。

当然问题在于,几乎不可能将使用限制在有意义的地方,并且允许在没有意义的地方使用它只是奇怪的。

我知道脚本语言中有一种运动可以尝试最小化代码行数,但是当你谈论编译语言时,可读性确实是关键,而且可能会冒犯你的意识对于风格,4线模型比反转if更清晰。

答案 13 :(得分:0)

我认为这是一个有用的结构,程序员会用它来强调代码中的重要内容,并且不再强调不重要的东西。它是关于写出意图揭示代码。

我使用这样的东西(在coffeescript中):

  

index = bla.find'a'
  如果index为-1,则返回

此代码中最重要的一点是如果没有找到任何内容就退出(返回) - 请注意我刚才用来解释意图的词语的顺序与代码

所以这个结构帮助我以一种更好地反映我的意图的方式进行编码。

认识到正确的英语或传统编程语言语法通常需要的顺序并不总是太令人惊讶,并不总是创造意义的最有效或最简单的方法。

有时候你需要让所有东西都出来,真正重新评估什么是最好的做事方式。

答案 14 :(得分:-1)

在问题之前把答案放在语法上是不正确的,为什么代码会有任何不同?