C# 还是回来?

C# 还是回来?,c#,.net,C#,.net,以下两个选项中,哪一个是性能和标准实践的最佳选择。NET如何在内部处理这两个代码段 代码1 还是代码2 If(result) { process1(); return; } process2(); 该返回将导致代码从if语句所在的任何方法返回,不会执行进一步的代码。没有返回的语句将直接从if语句中退出。不能说明性能,但代码1在我看来更清晰、更符合逻辑。如果在的中间跳出一个函数,如果块看起来非常混乱,很容易被忽略。 如果有共同的代码,则需要在I/EL块之后执行,然后选择1。 如果If

以下两个选项中,哪一个是性能和标准实践的最佳选择。NET如何在内部处理这两个代码段

代码1

还是代码2

If(result)
{
   process1();
   return;
}
process2();

该返回将导致代码从if语句所在的任何方法返回,不会执行进一步的代码。没有返回的语句将直接从if语句中退出。

不能说明性能,但代码1在我看来更清晰、更符合逻辑。如果在<代码>的中间跳出一个函数,如果块看起来非常混乱,很容易被忽略。

如果有共同的代码,则需要在I/EL块之后执行,然后选择1。 如果If-else块是函数中最后要做的事情,则选择2


就我个人而言,我总是使用选项1。如果有返回语句,它将出现在else块之后

如果删除第二版本剩余代码周围的大括号,这正是我所使用的。我更喜欢让函数的早期验证部分变得明显,然后我就可以开始工作了

尽管如此,这是一个意见的问题。只要你对此保持一致,选择一个并坚持下去


编辑:关于性能,发出的IL完全相同。选择一种或另一种款式,两者都不会受到惩罚。

就我个人而言,我总是希望尽快返回,因此我会选择以下产品:

if (result)
{
    // do something
    return;
}

// do something if not result

就性能而言,我怀疑两者是否有任何优势——这实际上取决于可读性和个人品味。我假设.NET会将您的第一个代码块优化为类似上面的内容。

我会使用
code 1
,因为如果我稍后在
if
语句之后添加一些内容,我仍然肯定它会执行,我不需要记住从
code 2
中删除
return
子句,我认为这无关紧要。你应该追求可读性,我认为括号越少越好。因此,我将不带最后2个括号返回(见下面的示例)。 在写这样的东西时,请不要考虑性能,它不会给你带来任何东西,只会在过早的阶段给你带来太多的复杂性

if(result)
{
  process 1
  return;
}

process 2

在任何正常情况下,性能差异(如有)都可以忽略不计

一种标准做法(除其他外)是尝试从一种方法中保留一个单一的退出点,以便谈判支持第一种选择


中间的“代码< >返回<代码>的实际实现最有可能跳转到方法的末尾,在该方法中,为该方法封装堆栈帧的代码是可能的,因此最终的可执行代码可能是两个代码相同的。

< P>我认为第二个选项对于多条件的情况更好。(例如验证)。 如果你在这些情况下使用第一个,你会得到丑陋的压痕

 if (con){
    ...
    return;
 }
 if (other con){
    ...
    return;
 }
 ...
 return;

这两种风格都很常见,宗教战争也一直围绕着它们展开

我通常会这样做:

  • 如果测试表示方法契约语义,例如检查输入参数的有效性,则选择选项2
  • 否则,选择选项1
然而,可以说一个更重要的规则是“对于下一个查看代码的开发人员来说,哪个更可读和/或更可维护?”


正如其他人所说,性能差异可以忽略不计。

我倾向于使用单出口,这在多线程环境中实现锁时非常有用,以确保释放锁。对于第一个实现,它更难做到。

我认为您不应该担心这里的性能。在这种情况下,可读性和可维护性更为重要

坚持一个退出点是一个很好的做法

然而,有时多次返回只会使代码更加清晰,特别是当您在代码开头附近有大量测试(即检查所有输入参数是否采用正确的格式)时,“if true”应该导致返回

即:


我倾向于从一个函数中有多个退出点。我个人认为它更清晰,在某些情况下可以更快。如果你检查了一些东西然后返回,程序将不会执行任何左命令。
正如HZC所说,如果您使用多线程应用程序,那么您最好使用第一个示例。不管怎样,对于小代码块来说,它不会有任何区别(甚至对于一些较大的代码也可能不会)。最重要的是,你要写下你对工作的感觉

我认为“单一退出点”被高估了。过于教条地坚持它会导致一些非常复杂的代码,这些代码实际上应该有多个退出点,或者被分割成更小的方法

我想说,两者之间的选择取决于语义

“如果某个条件为真,则执行此操作,否则执行此操作”完全映射到“如果为真”

if (isLoggedIn) {
    RedirectToContent();
} else {
    RedirectToLogin();
}
“如果出现某种情况,那么进行一些清理和纾困”更好地映射到代码2上。这称为保护模式。这使得代码的主体尽可能地被不必要的缩进保持正常、清晰和整洁。它通常用于验证参数或状态(检查是否有空值或缓存的内容,诸如此类)


在同一个项目中使用这两种形式并不少见。如我所说,使用哪种方法取决于你试图表达的内容。

如果非要我说,我会说更好的做法是“如果-其他”,而不是“隐含的”其他。原因是,如果其他人修改了您的代码,他们可以通过浏览很容易地捕捉到它

我记得在编程界有一场关于代码中是否应该有多个返回语句的大辩论。有人可能会说这是一个非常混乱的来源,因为如果在“if”语句中有多个循环,并且有条件返回,那么它可能会引起一些混乱

我通常的普拉克
if (date not set) return false;
age = calculateAgeBasedOnDate();
if (age higher than 100) return false;
...lots of code...
return result;
if (isLoggedIn) {
    RedirectToContent();
} else {
    RedirectToLogin();
}
if (user == null) {
    RedirectToLogin();
    return;
}

DisplayHelloMessage(user.Name);
type returnValue;
if(true)
{
 returnValue = item;
}
else
 returnValue = somethingElse;

return returnValue;
// C#
public static void @elseif(bool isTrue)
{
    if (isTrue)
        Process1();
    else
        Process2();
}
// IL
.method public hidebysig static void  elseif(bool isTrue) cil managed
{
  // Code size       15 (0xf)
  .maxstack  8
  IL_0000:  ldarg.0
  IL_0001:  brfalse.s  IL_0009
  IL_0003:  call       void elseif.Program::Process1()
  IL_0008:  ret
  IL_0009:  call       void elseif.Program::Process2()
  IL_000e:  ret
} // end of method Program::elseif


// C#
public static void @earlyReturn(bool isTrue)
{
    if (isTrue)
    {
        Process1();
        return;
    }
    Process2();
}
// IL
.method public hidebysig static void  earlyReturn(bool isTrue) cil managed
{
  // Code size       15 (0xf)
  .maxstack  8
  IL_0000:  ldarg.0
  IL_0001:  brfalse.s  IL_0009
  IL_0003:  call       void elseif.Program::Process1()
  IL_0008:  ret
  IL_0009:  call       void elseif.Program::Process2()
  IL_000e:  ret
} // end of method Program::earlyReturn
if (do_A_or_B = A)
  A()
else
  B()
if (NOT can_do_B)
{
  A() 
  return
}

B()