2012-02-05 4 views

ответ

10

Почему это просто; думать о том, что вы написали, как на самом деле быть этим:

object o = null; 
Console.WriteLine(("Is null: " + o) == null); // returns false 

Это испытание "Is null: " + o против null, который всегда будет false. Это связано с правилами приоритета оператора, где + - до ==.

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

Console.WriteLine("Is null: " + (o == null)); // returns true 

Как отмечалось в комментариях по Jim Rhodes:

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

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

Я также хотел бы указать, что мне очень нравится Ravadre, указанная в their answer; о том, почему был напечатан только «Ложный», а не весь текст, который вы пытались напечатать.

+3

Это одна из нескольких причин, почему вы должны ВСЕГДА использовать круглые скобки и никогда не полагаться на правила приоритета компилятора. –

+1

@JimRhodes Действительно; Я даже не пытаюсь самостоятельно запомнить правила приоритета оператора. Если это может быть * возможно, проблема, я явно указываю приоритет в своем коде. Этот пример - * также * случай, показывающий, что использование явного преобразования типов может вызвать путаницу. –

11

Приоритет оператора.

Попробуйте

Console.WriteLine("Is null: " + (o == null)); 

В своем коде, первый o добавляется "Is null: " строку, которая затем проверяется, если она равна нулю. Конечно, это не так, поэтому он оценивается как ложный. Ваш звонок так же, как если бы вы просто написать

Console.WriteLine(false.ToString()); 

Вот почему только «False», печатается, даже без вашей строки.

+0

Хорошее дополнение, указывающее, как он отображает только «False», а не «Is null: False». –

8

Другие ответы правильно поставили диагноз: приоритет оператора выше для конкатенации, чем равенство. Однако никто не обратил внимание на более фундаментальную ошибку в вашей программе, которая заключается в том, что вы вообще выполняете конкатенацию. Лучший способ, чтобы написать код является:

Console.WriteLine("is null: {0}", obj == null); 

Теперь не может быть проблемой, так как оператор старшинства выражение в вопросе имеет только один оператор.

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

+0

Однако, если конкатенация не включает выражения (только переменные, могут быть четными константами), и это коротко и просто? Во многих случаях конкатенация короче, яснее и работает лучше. Что вы думаете об этих аргументах? – Konstantin

Смежные вопросы