【问题标题】:Where is the bug in this Console.WriteLine statement?此 Console.WriteLine 语句中的错误在哪里?
【发布时间】:2009-08-21 14:05:50
【问题描述】:

如果你运行下面的代码,你会得到输出:

答案是:


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?

【问题讨论】:

  • 为了便于阅读,我会重写那些嵌套的 ?: 操作,或者至少将它们分成单独的行。
  • @Jason: 重写为 element.InnerHtml ??元素.InnerText ?? element.TagName 会很好
  • Console.WriteLine("答案是:{0}", element.InnerHtml !=null ? element.InnerHtml : element.InnerText != null ? element.InnerText : element.TagName);
  • @Jason 我已经论证了这一点,但正如我在下面所说的那样,这是别人的代码,这是他的偏好
  • @Hans,Console.WriteLine 使用 string.format 和 IFormattable

标签: c# .net operator-precedence


【解决方案1】:

您的The answer is: " +element.InnerHtml 优先于!= null。

改写为:

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

(加括号)

【讨论】:

    【解决方案2】:

    这是一个优先级问题。您的声明:

    "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 (&lt;br&gt;)。

    您在第一次测试中没有出现问题的原因是因为您正在单独评估 val,因此手动控制优先级。

    顺便说一句,我喜欢人们似乎认为他们在被无数其他人使用的软件中发现了错误的方式,而不是考虑他们可能做错了什么的最轻微的可能性:- )

    虽然老实说,我在许多人使用的一种产品中发现了错误(如果我没记错的话是 Microsoft COBOL 编译器),但那是由于签名/未签名的问题,而且我拥有一台最早的机器,它有超过512K RAM(启动代码检查以确保您有足够的内存并将 640K 视为负数)。

    不过,在 25 年中发现的一个错误非常少,因此您不应该立即认为该软件有问题。我的第一个想法始终是我不知何故搞砸了(我通常是对的,这让我很懊恼)。

    【讨论】:

    • 我不敢相信我是第一个发现这个可怕失误的人。这应该在测试版中被捕获。微软就是这样的菜鸟......哦,没关系。 :)
    【解决方案3】:

    因为还没有人回复??:

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

    这需要与?: 方法相同的一对额外()。

    【讨论】:

      【解决方案4】:

      两条写行写出不同结果的原因是您的逻辑中的一个细微错误。 (优先规则与您所期望的不同,如其他地方所述)

      行:

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

      评估 element.InnerHtml 是否不同于 null 其中行:

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

      评估“答案是:” +element.InnerHtml 是否不同于 null,它永远不会,因此结果将始终是 element.InnerHtml(并且文本“答案是”被认为是布尔表达式,因此不会被打印)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-03-30
        • 2017-09-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多