2009-08-21 2 views
0

Если запустить следующий код, который вы получите результат:Где ошибка в этой инструкции Console.WriteLine?

Ответ на: < бр >
< уш >

class Program 
{ 
    static void Main(string[] args) 
    { 
     HtmlElement element = new HtmlElement(); 
     element.InnerHtml = "<br>"; 

     string val = element.InnerHtml != null ? element.InnerHtml : element.InnerText != null ? element.InnerText : element.TagName; 
     Console.WriteLine("The answer is: "+val); // correct 
     Console.WriteLine("The answer is: " +element.InnerHtml !=null ? element.InnerHtml : element.InnerText != null ? element.InnerText : element.TagName); // bug? 
     Console.ReadLine(); 

    } 
} 
public class HtmlElement 
{ 
    public string InnerHtml { get; set; } 
    public string InnerText { get; set; } 
    public string TagName { get; set; } 
} 

Что случилось со второй линии, которая ожидается:

Ответ: < уш >

Просто для уточнения от ответа на какой-либо интересно серфера:

Console.WriteLine("The answer is: " +element.InnerHtml !=null ? element.InnerHtml : element.InnerText != null ? element.InnerText : element.TagName); // bug? 

в настоящее время оценивается как

Console.WriteLine(("The answer is : " + element.InnerHtml != null) ? element.InnerHtml : element.InnerText != null ? element.InnerText : element.TagName); // bug? 
+0

Для удобства чтения я бы переписал те вложенные?: Операции или по крайней мере разбить их на отдельные строки. –

+0

@Jason: Перепишите как * element.InnerHtml ?? element.InnerText ?? element.TagName * будет хороший – Greg

+0

Console.WriteLine ("Ответ: {0}"!, element.InnerHtml = нуль element.InnerHtml:! element.InnerText = нуль element.InnerText: элемент .Название тэга); –

ответ

18

Ваш The answer is: " +element.InnerHtml имеет приоритет над != null.

Rewrite как:

Console.WriteLine("The answer is: " + (element.InnerHtml !=null ? element.InnerHtml : element.InnerText != null ? element.InnerText : element.TagName)); // bug? 

(добавить скобка)

15

Это проблема старшинства. Ваше заявление:

"The answer is: " + element.InnerHtml !=null ? element.InnerHtml : ... 

следует оценивать как:

"The answer is: " + (element.InnerHtml !=null ? element.InnerHtml : ...) 
        <------------------- this first -------------------> 

, но на самом деле оценки как:

("The answer is: " + element.InnerHtml) !=null ? element.InnerHtml : ... 
<------------- this first ------------> 

Это последнее выражение всегда будет верно, так как "string" + anything != null, так что вы будете всегда получайте только element.InnerHtml(<br>).

Причина, по которой у вас нет проблемы в первом тесте, заключается в том, что вы оцениваете val отдельно, следовательно, вручную контролируете приоритет.

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

Хотя, честно говоря, я обнаружил ошибки в одном продукте, используемом многими людьми (компилятор Microsoft COBOL, если я правильно помню), но это было связано с подписанными/неподписанными проблемами, и у меня была одна из самых ранних машин с более чем 512 КБ ОЗУ (где код запуска проверен, чтобы убедиться, что у вас достаточно памяти, и обработало 640K как некоторое отрицательное количество).

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

+6

. Ваш последний абзац стоит upvote ... –

+1

Но ... мой код всегда безупречен! ЭТО ДОЛЖНО БЫТЬ MICROSOFT !!!!! – Randolpho

+0

Не могу поверить, что я первый, кто открыл эту ужасную ошибку. Это должно было попасть в бета-версию. Microsoft такие noobs ... О, неважно. :) – Chrisb

1

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

линия:

string val = element.InnerHtml != null ? element.InnerHtml : element.InnerText != null ? element.InnerText : element.TagName; 

оценивает если element.InnerHtml отличается от нуля, где в качестве линии:

Console.WriteLine("The answer is: " +element.InnerHtml !=null ? element.InnerHtml : element.InnerText != null ? element.InnerText : element.TagName); // bug? 

оценивает, является ли «ответ:» + element.InnerHtml отличается от нуля, которого он никогда не будет, поэтому результат всегда будет element.InnerHtml (а текст «Ответ» считается частью булевого выражения и поэтому не будет напечатано)

1

Потому что никто не ответил ?? еще:

Console.WriteLine("The answer is: " + (element.InnerHtml ?? 
    element.InnerText ?? element.TagName)); 

который нуждается в ту же пару дополнительных () как ?: подход.