0

我无法弄清楚为什么以下程序编译时没有警告,但在异常块中条件运算符给出了 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));
            }
        }
    }
}

我知道??运算符,我的问题是为什么异常处理程序中的第一行会给出 NullReferenceException。

4

2 回答 2

4
ex.Message + ex.InnerException

被转换成

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

这会检查其参数是否为 null,如果不是,则仅将它们转换为字符串。这意味着

ex.Message + ex.InnerException == null

false这样的表达

Environment.NewLine + ex.InnerException.Message

被评估。这会引发异常,因为ex.InnerException它是 null。

于 2014-07-01T08:12:11.990 回答
1

如果InnerException为 null 但ex.Message不是,则第一个表达式将评估为false并尝试访问ex.InnerException.Message为您提供NullReferenceException.

ex.InnerException.Message 在第二个表达式中,您仅在不ex.InnerException时才尝试访问,这就是它起作用的原因..

NullReferenceException当您尝试访问 null 的成员(方法、属性、字段等)时发生object。在您的第一个示例中:

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

您正在连接新行,message2并且您没有访问任何属性或方法。message2它只是为空值添加一个空字符串。查看以下文档string.Concat

该方法连接 str0 和 str1;它不添加任何分隔符。使用空字符串代替任何空参数。

如果你写:

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

然后你会得到一个例外。

于 2014-07-01T08:09:50.620 回答