使用条件运算符时的评估顺序

时间:2016-11-29 13:32:45

标签: c#

是否需要以下行为?

public class TestClass
{
    public int IntValue { get; set; }
}

TestClass instance = null;

// this line throws exception: Object reference not set to an instance of an object 
string test1 = "abc" + instance != null ? instance.IntValue.ToString() : "0";

// this works
string test2 = instance != null ? instance.IntValue.ToString() : "0";

// this works
string test3 = "abc" + (instance != null ? instance.IntValue.ToString() : "0");

更新

为什么这不会引发异常?

TestClass instance = null;
string test4 = "abc" + instance;
string test5 = "abc" + true;

2 个答案:

答案 0 :(得分:10)

您的问题是运营商优先级。 +排名高于!= ?:。你的行无效也可以这样写:

string test1 = ("abc" + instance) != null ? instance.IntValue.ToString() : "0";

表达式"abc" + instance 从不 null,即使instancenull。这意味着您的表达式始终评估为true,这使您在NullReferenceException instance.IntValue.ToString()表达式instance表达null时遇到instance != null ? instance.IntValue.ToString()

您可以使用parenthisation覆盖运算符优先级。这意味着您必须首先确保string test1 = "abc" + (instance != null ? instance.IntValue.ToString() : "0"); 被评估,将其括在括号中:

+

<强>更新

就更新中的问题而言:这些表达式不会抛出错误,因为有关字符串null运算符实现的两个细节:

  1. 只要您在另一方拥有有效字符串,它就可以容忍ToString值。
  2. 由于System.Object方法已在ToString中实施,因此任何值都可以转换为PHImageManager的字符串。因此,可以将非字符串值添加到字符串中(仅右侧的 )。

答案 1 :(得分:2)

是。它是。这是因为首先评估"abc" + instance。然后它检查它是否为空(显然不是真的)。然后在true路径中,它尝试获取instance的值,该值为null,从而产生此异常。

评估顺序在语言内确定,该语言指定+ is being handled before !=