Вызов методов внутри if () - C # - PullRequest
13 голосов
/ 24 февраля 2009

У меня есть пара методов, которые возвращают bool в зависимости от их успеха, есть что-то не так с вызовом этих методов внутри IF ()?

//&& makes sure that Method2() will only get called if Method1() returned true, use & to call both methods
if(Method1() && Method2())
{
    // do stuff if both methods returned TRUE
}

Method2 () не нужно запускать, если Method1 () возвращает FALSE.

Дайте мне знать, что есть проблема с кодом выше.

спасибо.

РЕДАКТИРОВАТЬ: , поскольку в коде не было ничего плохого, я приму наиболее информативный ответ ... добавил комментарий для решения проблемы "newbie & &&"

Ответы [ 10 ]

21 голосов
/ 24 февраля 2009

Я добавлю, что вы можете использовать & operator (вместо &&), чтобы гарантировать, что оба метода вызываются, даже если левая часть равна false, если по какой-то причине в будущем Вы хотите избежать короткого замыкания.

Обратное работает для | operator, где, даже если левое условие оценивается как true, правое условие также будет оценено.

19 голосов
/ 24 февраля 2009

Нет, нет ничего плохого в вызовах методов в условии if. На самом деле, это может быть отличным способом сделать ваш код более читабельным!

Например, написать намного чище:

private bool AllActive()
{
    return x.IsActive && y.IsActive && z.IsActive;
}

if(AllActive())
{
    //do stuff
}

чем:

if(x.IsActive && y.IsActive && z.IsActive)
{
    //do stuff
}
2 голосов
/ 24 февраля 2009

Хотя, как все говорят, в этом нет ничего «неправильного», и во многих случаях вы делаете именно то, для чего предназначен язык.

Имейте в виду, однако, что для удобства обслуживания, если у Method2 есть побочные эффекты (то есть, он меняет состояние чего-то), может быть не очевидно, что эта функция не вызывается (хороший программист обычно знает, но даже у хороших программистов иногда бывают мозговые пердежи).

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

2 голосов
/ 24 февраля 2009

Я бы порекомендовал это, только если методы являются чистыми (без побочных эффектов) функциями.

2 голосов
/ 24 февраля 2009

Как бы полезны они ни были, точки последовательности могут сбивать с толку. Если вы действительно не понимаете это, неясно, что Method2 () может вообще не вызываться. С другой стороны, если вам нужно, чтобы оба метода вызывались И они возвращали true, что бы вы написали? Вы могли бы пойти с

bool result1 = Method1();
bool result2 = Method2();
if (result1 && result2)
{
}

или вы могли бы пойти с

if (Method1())
    if (Method2())
    {
    }

Так что я думаю, что ответ на ваш вопрос ИМХО, нет, не совсем понятно, что вы имеете в виду, даже если поведение будет тем, что вы описываете.

1 голос
/ 24 февраля 2009

Не должно быть никаких проблем.

Обычное поведение состоит в том, что Method1 () будет выполняться, и если он вернет true, будет выполняться Method2 (), и в зависимости от того, что возвращает Method2 (), вы можете / не можете вводить оператор if ().

Теперь, предполагает , что компилятор генерирует код, который выполняется таким образом. Если вы хотите быть абсолютно уверенным , что Method2 () не будет выполняться, если только Method1 () не вернет true, вы можете написать это так:

if( Method1() )
{
  if( Method2() )
  {
    // do stuff if both methods returned TRUE 
  }
}

Но я всегда замечал, что ваш код будет работать так, как ожидалось, поэтому, вероятно, в этом нет необходимости.

1 голос
/ 24 февраля 2009

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

0 голосов
/ 24 февраля 2009

выглядит хорошо для меня, но есть некоторые предостережения ... Это НЕ та вещь, где применяются общие правила.

Мои рекомендации :

  • Если имена методов короткие и их не так много, то все хорошо.
  • Если у вас слишком много операторов / вызовов методов внутри оператора if, вы, скорее всего, сравниваете более одного «набора» вещей. Разбейте эти «наборы» и введите временные переменные.
  • «Слишком много» субъективно, но обычно больше, чем около 3
  • Когда я говорю «имена методов короткие», я говорю не только об именах, но и о параметрах, которые они принимают. В основном усилия, требуемые для кого-то, чтобы прочитать это. Например, if( Open(host) ) меньше if( WeCouldConnectToTheServer ). Общий размер всех этих предметов - то, к чему это сводится.
0 голосов
/ 24 февраля 2009

Лично я бы рассмотрел

if(Method1() && Method2())
{
    // do stuff if both methods returned TRUE
}

быть плохой практикой. Да, это работает в текущей среде, но так же

if(Method1())
{
  if (Method2())
  {
    // do stuff if both methods returned TRUE
  }
}

Но будет ли это работать во ВСЕХ средах? Будут ли так работать будущие, возможно, не Microsoft, компиляторы C #? Что если ваша следующая работа предполагает использование другого языка, на котором всегда будут вызываться оба метода? Я бы не стал полагаться на эту конкретную конструкцию не потому, что она неправильная, а потому, что она не решает никаких серьезных проблем и может стать неправильной в будущем

0 голосов
/ 24 февраля 2009

Nothin 'неправильно.

На самом деле ... я бы не назвал их Method1 и Method2. Что-то более наглядное. Возможно, пассивное звучание (например, StuffHasHappened или DataHasLoaded)

...