2015-09-14 3 views
-7

У меня есть сегмент кода, который генерирует исключение NullReferenceException. Сегмент кода такой.Короткое замыкание Если условие не работает

if (string.IsNullOrWhiteSpace(user.FirstName) && !(user.FirstName.Length <= 64)) 
{ 
    // Some Code 
} 

Здесь, если условие первого следует проверить, если user.FirstName является Null или переформатирования. Когда значение user.FirstName равно null, этот сегмент кода генерирует NullReferenceException. Я предполагаю, что это выбрано путем проверки Lengthuser.FirstName, но так как это проверка короткого замыкания, первое из них не должно удовлетворять условию и выполнять код внутри блока if. Или я здесь что-то пропустил.

+1

Основная проблема. Что второй критерий не называется или что критерий бросает исключение NullReferenceException, чего вы не ожидали? –

+0

Почему 9 голосов? –

+0

Я думаю, что вопрос непонятен, и ОП не отвечает. –

ответ

1

В вашем примере вы можете иметь две различные причины для NullReferenceException:

- Value `user` is null; 
- `user.FirstName` is null. 

Я предполагаю, что вы проверили уже, если user не равно нулю, так что позволяет пропустить этот один.

Теперь допустим, что user.FirstName имеет значение null, что происходит?

Первое условие string.IsNullOrWhiteSpace(user.FirstName) приведет к true. Достаточно ли этого для того, чтобы оператор if выполнял внутренний блок кода или должен также быть оценено второе условие?

Давайте посмотрим на эту истину стол:

A && B  = RESULT 
-------------------- 
False False = False 
False True = False 
True False = False 
True True = True 

So при использовании && -оператором общее условие только справедливо, когда оба subconditions истинны. Поэтому, когда первое условие истинно, второе еще нужно оценить. Простой перевод истины таблицы в соответствии с C# будет (где ??? означает: Не важно):

A && B  = RESULT 
-------------------- 
False ??? = False 
True False = False 
True True = True 

Так при проверке второго условия, то свойство user.FirstName.Length читается, в результате чего ваш NullReferenceException.

Как предотвратить это. Как и другие люди заявляли, вы, вероятно, хотите, чтобы выполнить блок кода, если: FirstName является NULL ИЛИ Empty ИЛИИЛИ Пробел больше, чем 64. Текущие проверки состояние, в основном, если FirstName является NULL И больше чем 64.

Итак ... использовать || -оператора:

if (string.IsNullOrWhiteSpace(user.FirstName) || !(user.FirstName.Length <= 64)) 

или более четкое:

if (string.IsNullOrWhiteSpace(user.FirstName) || (user.FirstName.Length > 64)) 

C# истины стол будет:

A || B  = RESULT 
-------------------- 
False False = False 
False True = True 
True ??? = True 

В котором вы можете Клирю видеть «короткое замыкание» часть.

5

Вторая часть выполняется только при

string.IsNullOrWhiteSpace(user.FirstName) 

результаты в действительности. Так что вам нужно

!string.IsNullOrWhiteSpace(user.FirstName) && !(user.FirstName.Length <= 64) 

или

string.IsNullOrWhiteSpace(user.FirstName) || !(user.FirstName.Length <= 64) 

в зависимости от ваших требований. Кроме того, user может быть null, и в этом случае короткое замыкание не поможет.

0

&& не замыкается, как вы ожидаете, это совершенно наоборот.

Необходимо проверить оба условия, если первое верно, и только если оба они истинны, он выполнит блок внутри: если первое условие истинно (то есть user.FirstName равно null), тогда ему необходимо проверить, второй является истинным, поэтому ваше исключение (поскольку user.FirstName всегда будет нулевым, если оно пустое или пустое - при проверке Length).

Edit: так как выше пункт, кажется, не ясно, для некоторых людей: Я не говорю, что && не короткое замыкание (он бы короткое замыкание, если первое условие было false), я м говоря, что это не от короткого замыкания, как ожидается ОП

+0

Упомяните, пожалуйста, о нижнем уровне? – Jcl

+0

Хотя ваш ответ технически корректен, он не имеет никакого отношения к проблеме. Не имеет значения, проверяет ли оператор && только один или оба критерия, проблема в том, что пользователь имеет значение null. –

+0

@MartinMulder кажется, что OP спрашивает, почему он не замыкается, поэтому я попытался объяснить *, что * – Jcl

1

Перед отправкой не работы утверждения давайте проанализируем вашу проблему (# решения C содержат млрд строк кода: вы действительно думаете, что такие общая конструкция, как if может быть не в состоянии работать?)

кажется, что вы хотите проверить, если имя пользователя является недействительными один:

  1. если имя пользователя является нулевым или пустым или белым пространством
  2. или если он слишком длинные (более 64 символов)

реализация Теперь уже ясно:

const int USER_NAME_MAX_LENGTH = 64; 

    if (string.IsNullOrWhiteSpace(user.FirstName) || 
     user.FirstName.Length > USER_NAME_MAX_LENGTH) { 
    // user name is invalid 
    ... 
    } 
Смежные вопросы