Цепная структура IF - PullRequest
       20

Цепная структура IF

7 голосов
/ 17 декабря 2008

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

Как я могу проверить эти два условия в одном условии "если"?

В настоящее время я должен сделать что-то вроде этого:

if (myObject != null)
{
    if (myObject.Id != pId)
    {
        myObject.Id = pId;
        myObject.Order = pOrder;
    }
}

Я бы хотел что-то вроде этого:

if (myObject != null && myObject.Id != pId)

Я хочу оценить второе условие, только если первое было истинным.

Может быть, я что-то упускаю, и поэтому мне нужна ваша помощь; -)

Ответы [ 10 ]

43 голосов
/ 17 декабря 2008
if(myObject != null && myObject.Id != pId)
{
   myObject.Id = pId;
   myObject.Order = pOrder;
}

&& - логический тест на короткое замыкание - он оценивает правую сторону только в том случае, если левая сторона истинна. Контраст с "a & b", который всегда оценивает обе стороны (и делает побитовые "и")

10 голосов
/ 17 декабря 2008

Следует подчеркнуть, что кратковременная оценка && в if () является абсолютно гарантированной в соответствии со стандартами языка (C, C ++, Java и C #). Так было со времен первого издания K & R " C Programming Language ".

Вам не о чем беспокоиться: «Мой компилятор это реализует?». Если определенно делает .

5 голосов
/ 17 декабря 2008
if (myObject != null && myObject.Id != pId)
{
//bla
}

это безопасно, потому что оператор && оценивается лениво, что означает, что если LHS ложно, RHS никогда не оценивается

4 голосов
/ 17 декабря 2008

Этот код сначала проверяет, не является ли myObject ненулевым, в случае, если оно истинно, он проверяет следующее условие, а в случае, если оно не истинно, он не проверяет следующее условие и не выполняет код.

if (myObject != null && myObject.Id != pId)
{
  myObject.Id = pId;
  myObject.Order = pOrder;
}
3 голосов
/ 17 декабря 2008

У вас есть много хороших ответов о том, как это сделать. Я просто хочу предупредить о том, как этого не делать. Не включайте одиночный тест для id = pid в блок try-catch. Это расточительно и потребовало бы введения проверки исключений, чтобы поймать неисключительное условие. Это настолько плохая идея, что я даже не собираюсь иллюстрировать это примером.

1 голос
/ 12 января 2010

Вы можете использовать & для оценки двух условий, но если вы хотите проверить второе, только если первый элемент имеет значение true, вы можете использовать &&.

На португальском мы называем это: «И com curto circuito».

if (myObject != null && myObject.Id != pId)

если myObject имеет значение false, вы не можете проверить myObject.Id, поскольку myObject имеет значение null и вы не можете получить доступ к свойству нулевого объекта.

:::::::::::::::::::::::

a b a && b

верно верно верно

истина ложь ложь

ложь правда ложь

ложь ложь ложь

:::::::::::::::::::::::

1 голос
/ 17 декабря 2008

Так как я думаю, что это может быть полезно для других, рассматривающих этот вопрос в будущем. Как уже говорилось, использование && обеспечивает необходимую вам функциональность. Но следует также отметить, что функциональность, которую вы боялись, заключалась в том, что обе стороны будут оцениваться независимо от результата первой оценки, используя & вместо &&. Итак:

//DO NOT USE THIS CODE
//this will throw an exception if myObject is null
//because myOject.Id != pId will still be evaluated
if(myObject != null & myObject.Id != pId)
{   
   myObject.Id = pId;
   myObject.Order = pOrder;
}

Опять же, для этого примера вам НЕ нужен этот код. Я просто хотел добавить это к беседе, потому что могут быть случаи (хотя я никогда не находил), где вам нужна эта функциональность, например:

//always run both methods
if(MethodA() & MethodB())
{   
   //do stuff only when both methods return true
}
1 голос
/ 17 декабря 2008

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

</p> <pre><code>if(myObject != null andAlso myObject.Id != pId) { myObject.Id = pId; myObject.Order = pOrder; }

Я думаю, делает то же самое, но есть альтернатива!

Редактировать: изменено C # на VB.net выше

1 голос
/ 17 декабря 2008
if(!(myObject == null || myObject.Id == pId))
{
   myObject.Id = pId;
   myObject.Order = pOrder;
}
1 голос
/ 17 декабря 2008
if (myObject != null && myObject.Id != pId)
{
     myObject.Id = pId;
     myObject.Order = pOrder;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...