16

可能重复:
为什么在方法结束时返回是一种好习惯

我想知道在一个方法中使用多个 RETURN 语句是否可以被认为是一种好的做法,以及为什么。如果没有,我想知道您将如何以不同的方式重写代码。

public string GetNominativeById(int? candidateId)
        {
            if (candidateId.HasValue)
                return repepositoryCandidate.GetById(candidateId.Value).Nominative;
             else
                return string.Empty;
            }
        }

一次返回

 public string GetNominativeById(int? candidateId)
    {
        string result;
        if (candidateId.HasValue)
            result =  repepositoryCandidate.GetById(candidateId.Value).Nominative;
         else
            result =  string.Empty;

        return result;
        }
    }
4

11 回答 11

28

你实际上并不需要else

string GetNominativeById(int? candidateId)
{
    if (!candidateId.HasValue)  
        return string.Empty;

    return repepositoryCandidate.GetById(candidateId.Value).Nominative;
}

考虑这种反箭头模式

if (condition1)
{
    if (condition2)
    {
        if (condition3)
        {
            // code lines
        }
    }
}

立即返回的方式将使您的代码更具可读性:

if (!condition1) return;
if (!condition2) return;
if (!condition3) return;

// code lines
于 2012-10-02T06:52:24.257 回答
14

不,在一个方法中有多个退出点被认为是不好的做法而不是好的做法。如果有单点退出,则更容易遵循代码。

但是,当方法像示例中一样小时,无论如何遵循代码并不难,因此具有多个退出点并不是问题。如果它使代码更简单,您可以很好地使用多个return语句。

于 2012-10-02T06:53:59.083 回答
10

尽管出于可读性目的,您应该努力只使用一个 return 语句,但有几种模式涉及多个 return 语句。一个例子是Guard Clause

保护条款示例:

  public Foo merge (Foo a, Foo b) {
    if (a == null) return b;
    if (b == null) return a;
    // complicated merge code goes here.
  }

一些风格指南会让我们用一个单一的回报来写这个,如下所示

  public Foo merge (Foo a, Foo b) {
    Foo result;
    if (a != null) {
      if (b != null) {
        // complicated merge code goes here.
      } else {
        result = a;
      }
    } else {
      result = b;
    }
    return result;
  }

另一种情况是 switch 语句,当您可能希望从每种情况下返回时:

switch(foo)
{
   case "A":
     return "Foo";
   case "B":
     return "Bar";
   default:
     throw new NotSupportedException();
}

我会将您的代码重写为:

        public string GetNominativeById(int? candidateId)
        {
            return candidateId.HasValue 
                ? repepositoryCandidate.GetById(candidateId.Value).Nominative;
                : string.Empty;
        }

归根结底,请记住您(和其他开发人员)将多次阅读您的代码,因此请确保其可读性和明显性。

于 2012-10-02T06:52:14.053 回答
6

看看维基百科上的以下文章。您要问的是您是否应该遵循结构化编程的 SESE(单入口,单出口)原则。

于 2012-10-02T06:53:16.933 回答
3

拥有更多的 return 语句并没有错,有时它实际上可以帮助您缩小代码并节省一些不必要的变量分配,就像 Cuong Le 指出的那样。:D

于 2012-10-02T07:00:53.480 回答
3

结构化编程的规则之一是每个方法都应该有一个入口和出口点。有一个退出点(return在这种情况下是语句)意味着任何清理,例如调用 Close 或 Dispose,只需要发生一次。拥有多个出口点对小型方法的影响很小,但随着方法复杂性的增加而增加,在这种情况下可能很容易遗漏一个案例,或者代码被重构或修改。

于 2012-10-02T06:53:19.637 回答
2

养成return在方法末尾添加的习惯,因此您必须关闭所有活动对象(如果有

public string GetNominativeById(int? candidateId)
{
    string _returnValue = string.Empty;
    if (candidateId.HasValue)
        _returnValue repepositoryCandidate.GetById(candidateId.Value).Nominative;
     else
        _returnValue =  string.Empty;

    return _returnValue;
}

旁注:三元运算符并不是这个问题的真正答案(我认为),因为在某些情况下,您的IF语句中有多个代码块。

于 2012-10-02T06:51:35.413 回答
2

这一切都取决于

  • 您与其他开发人员一起使用的编码标准
  • 和实际代码可读性(所以个人对代码的看法)

一般来说,当if/else变得太多时,我会使用return

所以不要使用:

if(...)
{
    if(...)
    {
        if(...)
        {
        }
    }
    else if(...)
    {
    }
     ..
    else
    {
    }
}

使用return

if(!...)
   return;

if(!...)
   return;
于 2012-10-02T06:53:18.657 回答
1

你实际上不能在一个方法中使用多个返回语句,你在代码中所做的,你使用了 if else 语句,所以无论如何只会执行一个。你的代码对我来说似乎很好。

于 2012-10-02T06:53:36.503 回答
1

是的,如果有必要,那么为什么不使用多个 return 语句。性能不会有问题。

要重写此代码:

public string GetNominativeById(int? candidateId)
{
    if (candidateId.HasValue)
          return repepositoryCandidate.GetById(candidateId.Value).Nominative;

    return string.empty;
}

或使用“三元运算符”。

public string GetNominativeById(int? candidateId)
{
     return candidateId.HasValue ? repepositoryCandidate.GetById(candidateId.Value).Nominative : string.Empty;  
}
于 2012-10-02T06:54:50.567 回答
0

为什么不?但你不需要别的。

public string GetNominativeById(int? candidateId)
        {
            if (candidateId.HasValue)
                return repepositoryCandidate.GetById(candidateId.Value).Nominative;
            return string.Empty;
        }
于 2012-10-02T06:51:36.877 回答