我无法弄清楚为什么以下程序在没有警告的情况下编译,但在异常块中,条件运算符给出了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。
答案 0 :(得分: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
为空,因此抛出异常。
答案 1 :(得分:1)
如果InnerException
为空,但ex.Message
不是,那么第一个表达式将评估为false
并尝试访问ex.InnerException.Message
,它将为您提供NullReferenceException
。
在第二个表达式中,如果ex.InnerException.Message
ex.InnerException
,这就是为什么它工程..
NullReferenceException
的成员(方法,属性,字段等)时,会出现 object
。在您的第一个示例中:
message1 + message2 == null ? "" : Environment.NewLine + message2;
您正在使用message2
连接新行,并且您没有访问message2
上的任何属性或方法。它只是为空值添加一个空字符串。请查看{{3} } string.Concat
:
该方法连接str0和str1;它不会添加任何分隔符。 使用空字符串代替任何空参数。
如果你写:
message1 + message2 == null ? "" : Environment.NewLine + message2.ToString();
然后你会得到一个例外。