Где ошибка в этой инструкции Console.WriteLine? - PullRequest
0 голосов
/ 21 августа 2009

Если вы запустите следующий код, вы получите вывод:

Ответ:


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?

Ответы [ 4 ]

18 голосов
/ 21 августа 2009

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

Переписать как:

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

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

15 голосов
/ 21 августа 2009

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

"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 КБ ОЗУ (где проверен код запуска, чтобы убедиться, что у вас достаточно памяти, и он обработал 640 КБ как некоторое отрицательное значение).

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

1 голос
/ 21 августа 2009

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

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

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

1 голос
/ 21 августа 2009

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

строка:

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 (а текст «Ответ» считается частью булево выражение и поэтому не будет напечатано)

...