Является ли хорошей практикой больше использовать один оператор RETURN в методе?

Возможный дубликат:
Почему хорошая практика возвращается в конце метода

Я хотел бы знать, можно ли считать, что хорошая практика использует несколько операторов RETURN в методе и почему. Если нет, я хотел бы знать, как вы переписываете код по-другому.

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

С одним RETURN

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

        return result;
        }
    }

Ответ 1

Нет, он считал плохую практику не настолько хорошей практикой, чтобы иметь несколько точек выхода в методе. Легче следить за кодом, если есть одна точка выхода.

Однако, когда метод такой же малый, как в примере, в любом случае не сложно следовать коду, поэтому наличие нескольких точек выхода на самом деле не является проблемой. Если код упрощает, вы можете использовать несколько операторов return.

Ответ 2

Вам действительно не нужно 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

Ответ 3

Хотя вы должны стремиться иметь только один оператор return для целей удобочитаемости, это несколько шаблонов, которые включают несколько операторов возврата. Одним из примеров является Предложение охраны.

Пример предложения охраны:

  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;
        }

В конце дня помните, что вы (и другие разработчики) будете много раз читать свой код, поэтому убедитесь, что он читабельны и очевидны.

Ответ 4

Взгляните на следующую статью в Википедии. Вы спрашиваете, следует ли вам следовать принципу SESE (single entry, single exit) из структурированного программирования.

Ответ 5

нет ничего плохого в том, что у вас больше указаний на возврат, иногда это помогает вам минимизировать ваш код и сохранять ненужную переменную, как то, что указал Cuong Le.: D

Ответ 6

Все это зависит от

  • стандарт кодирования, который вы используете с другими разработчиками
  • и фактическая читаемость кода (поэтому личное восприятие кода)

В общем случае, когда if/else становится слишком много, вместо этого я использую return.

Итак, вместо использования:

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

используйте return:

if(!...)
   return;

if(!...)
   return;

Ответ 7

сделать привычкой добавлять 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;
}

side-note: Тернарный оператор на самом деле не является ответом на это (я думаю), потому что в вашем случае IF есть несколько случаев, когда вы используете несколько кодовых блоков.

Ответ 8

Одно из правил Структурированное программирование утверждает, что каждый метод должен иметь одну точку входа и выхода. Наличие одной точки выхода (оператор return в этом случае) означает, что любая очистка, например вызов Close или Dispose, должна произойти только один раз. Воздействие наличия нескольких точек выхода незначительно на небольших методах, но увеличивается по мере увеличения сложности метода, когда это может быть легко пропустить, или как код как реорганизованный или измененный.

Ответ 9

на самом деле вы не можете использовать более одного оператора возврата в одном методе, что вы делали в своем коде, вы использовали оператор if else, так что только один будет выполнен в любом случае. Ваш код мне кажется хорошим.

Ответ 10

Да, если это необходимо, то почему бы не использовать несколько операторов возврата. Не будет проблем с производительностью.

Чтобы переписать этот код:

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;  
}

Ответ 11

Почему бы и нет? Но вам больше не нужно.

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