Метод, который делает условный возврат метода, вызывающего его? - PullRequest
5 голосов
/ 03 апреля 2010

Хорошо, это может быть немного хакерской, но потерпите меня :) Фон в том, что я устал от методов, которые некоторые if-операторы, которые портят отступ для всего метода, например:

public SomeClass DoStuff(string inputStr)
{
  SomeClass result =null;
  if (IsOpenFilter(inputStr))
  {
    ....
  }

  return result;
}

Так что я подумал, не было бы замечательно, если бы я мог сделать что-то вроде этого:

public SomeClass DoStuff(string inputStr)
{
  Require(IsOpenFilter(inputStr),null);


  ....

  return result;
}

Этот случай может быть покрыт контрактами кода в некоторой форме, если так, пожалуйста, исправьте меня:)

Идея состоит в том, что если утверждение не оценивается как истинное, оно вернет ноль. Если бы для метода не было возвращаемого типа, это было бы просто: Require (IsOpenFilter (inputStr));

Так что, думаю, есть два вопроса, можно ли это как-нибудь сделать? Я озадачен тем, как сделать условный возврат при вызове метода.

Другой вопрос, это хорошая идея? Немного странно, чтобы подобная мартышка была похожа на этот язык, но я бы предпочел способ чтения кода. Я был бы еще чище, если бы его можно было поместить в атрибут над методом: [Require (IsOpenFilter (inputStr))]]

Ответы [ 2 ]

7 голосов
/ 03 апреля 2010

Я согласен с Андерсом: переверни условие и вернись рано. «Единственная точка возврата» была полезна, когда вам нужно было явно выполнить кучу очистки ресурсов в этой точке возврата; с finally блоками, using операторами и сборкой мусора, это даже не полезное руководство, IMO. Каждый раз, когда вы обнаруживаете, что делаете что-то просто , чтобы получить одну точку возврата, подумайте, действительно ли это делает код более читабельным.

Я почти всегда нахожу, что если в какой-то момент в коде я знаю возвращаемое значение и нет других действий, которые я хочу предпринять в методе, лучше всего немедленно вернуться. Заставлять читателей просматривать оставшуюся часть метода на всякий случай , есть другое действие, которое не является ни элегантным, ни полезным, ИМО.

Я думаю, это хорошо, что метод не может указать, что он должен заставить вызывающего вернуться - эта способность звучит как кошмар читабельности. Сказав это, я рассмотрел новый тип условного оператора возврата:

return? expression;

Это вернет оцененное значение expression, если оно не равно нулю; Вы можете использовать его для типов, не допускающих значения NULL, например:

int Foo()
{
    return? Bar(); // Where Bar() has a return type of int?
    ...
}

По сути, это будет оператор возврата, эквивалентный оператору слияния нуля.

В вашем случае это не поможет, учтите - вы хотите вернуть ноль раньше ...

3 голосов
/ 03 апреля 2010

А как насчет переписывания вашего первого примера следующим образом:

public SomeClass DoStuff(string inputStr) 
{ 
  if (!IsOpenFilter(inputStr)) 
      return null;

  SomeClass result =null; 

  // Some code .... 

  return result; 
} 

Похоже, вы пытаетесь придерживаться старого соглашения об одной точке возврата в каждой функции. Короче говоря: одно возвращение - это наследие языков с явной обработкой ресурсов. Длинная история доступна в некоторых старых сообщениях SO:

...