views:

315

answers:

3

If you run the following code you get the output:

The answer is: <br>
<br>

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; }
}

What's happened to the second line, which is expected to be:

The answer is: <br>

Just to clarify on the answer for any wondering surfer:

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

is being evaluated as

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

Your The answer is: " +element.InnerHtml has precedence over the != null.

Rewrite as:

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

(add parenthesis)

CMerat
+15  A: 

It's a precedence problem. Your statement:

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

should be evaluating as:

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

but is actually evaluating as:

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

That last expression will always be true, since "string" + anything != null, so you'll always get just the element.InnerHtml (<br>).

The reason you don't have the problem in the first test is because you're evaluating val separately, hence manually controlling the precedence.

As an aside, I love the way people seem to assume they've found a bug in a piece of software being used by untold millions of other people, rather than considering the slightest possibility that they may have done something wrong :-)

Although to be honest, I have found bugs in one product used by many people (a Microsoft COBOL compiler if I remember correctly) but that was due to signed/unsigned issues and I had one of the very earliest machines with more than 512K RAM (where the startup code checked to ensure you had enough memory and it treated 640K as some negative amount).

Still, one bug found in a quarter century is pretty low so it's not like you should assume the software is at fault immediately. My first thought is always that I've stuffed up somehow (and I'm usually right, much to my chagrin).

paxdiablo
Your last paragraph alone is worth an upvote...
Magnus Johansson
But... my code is always flawless! IT MUST BE MICROSOFT!!!!!
Randolpho
I can't believe I am the first one to discover this horrible misstep. This should have been caught in beta. Microsoft are such noobs...Oh, nevermind. :)
Chrisb
+1  A: 

The reason why the two writelines write differrent results is a subtle bug in your logic. (the precedence rules differs from what you expect, as noted elsewhere)

the line:

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

evaluates if element.InnerHtml is different from null where as the line:

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

evaluates whether "The answer is: " +element.InnerHtml is different from null, which it will never be, so the result will always be element.InnerHtml (and the text 'The answer is' is considered a part of the boolean expression and will therefore not be printed)

Rune FS