Why does the following conditional operator "?:" compile but give a run-time error

147 Views Asked by At

I cannot figure out why the following program compiles without warnings, but in the exception block the conditional operator gives a NullReferenceException.

using System;

namespace Playground
{
    class Program
    {
        static void Main(string[] args)
        {
            string message1 = "First message.";
            string message2 = null;
            // This works without a problem
            Console.WriteLine(message1 + message2 == null ? "" : Environment.NewLine + message2);
            Console.ReadKey();

            try
            {
                throw new Exception("Now with an exception.");
            }
            catch (Exception ex)
            {
                // This will give a NullReferenceException:
                Console.WriteLine(ex.Message + ex.InnerException == null ? "" : Environment.NewLine + ex.InnerException.Message);
                // ..But this will work:
                Console.WriteLine(ex.Message + (ex.InnerException == null ? "" : Environment.NewLine + ex.InnerException.Message));
            }
        }
    }
}

I know about the ?? operator, my question is about why the first line in the exception handler gives a NullReferenceException.

2

There are 2 best solutions below

5
On BEST ANSWER
ex.Message + ex.InnerException

is converted into

string.Concat(ex.Message, ex.InnerException);

this checks its arguments for null and only converts them to strings if they are not. This means that

ex.Message + ex.InnerException == null

is false so the expression

Environment.NewLine + ex.InnerException.Message

is evaluated. This throws an exception since ex.InnerException is null.

1
On

if InnerException is null but ex.Message isn't, then the first expression will evalute to false and will try to access ex.InnerException.Message which is giving you the NullReferenceException.

In the second expression you are trying to access ex.InnerException.Message only if the ex.InnerException is not null and that's why it works..

NullReferenceException occurs when you are trying to access a member (method, property, field etc.) of a null object.In your first example:

message1 + message2 == null ? "" : Environment.NewLine + message2;

you are concatenating the new line with message2 and you are not accessing any properties or methods on message2.It just adds an empty string for null values.Take a look at the documentation of string.Concat:

The method concatenates str0 and str1; it does not add any delimiters. An Empty string is used in place of any null argument.

If you write:

message1 + message2 == null ? "" : Environment.NewLine + message2.ToString();

Then you will get an exception.