我正在尝试构建一个类似下面的字符串,我注意到它在使用后会被切断?运算符,无论前一个值是否为空。
"Some Text" + System.Environment.NewLine +
varOne.ToString() ?? string.Empty + System.Environment.NewLine +
varTwo.ToString()...
字符串包含的所有内容(无论值是多少)都取决于varOne(Some Text + newline + varOne),除非我删除??运营商。看了一下之后,我发现这不是首选的方法,而且我应该使用字符串构建器,但我只是好奇为什么会发生这种情况?
答案 0 :(得分:6)
?? operator被称为null-coalescing运算符并且习惯于 为可空值类型或引用类型定义默认值。它 如果操作数不为null,则返回左侧操作数;否则它 返回正确的操作数。
这意味着,??
之后的内容仅被分配,如果之前的内容为空。
所以
string sNull = null;
string s = sNull ?? "TADA";
s
将为TADA
和
string sNull = null;
string s = sNull ?? "TADA";
string sNormal = s ?? "NOT TADA";
sNormal
也是TADA
答案 1 :(得分:2)
尝试:
"Some Text" + System.Environment.NewLine +
(varOne == null ? string.Empty : varOne.ToString()) + System.Environment.NewLine +
varTwo.ToString()...
答案 2 :(得分:1)
varOne.ToString()
永远不会null
。并且假设我们有a ?? b + c + d ?? n
,如果a != null
整个事情都流向a
而不是a + (d ?? n)
(因为运算符优先)
答案 3 :(得分:1)
?? operator表示“如果此运算符之前的东西不为null,请使用它,否则请使用此运算符之后的东西”。
你可能会感到困惑的是构成“此运算符之前的事物”的内容。在你的情况下,这就是全部:
"Some Text" + System.Environment.NewLine + varOne.ToString()
那永远不会是空的。即使varOne.ToString()返回null(这将是varOne类中的错误,因为ToString()永远不会返回null),将字符串与null连接的结果是原始字符串。绝对没有上述情况可能导致null的情况。
现在, varOne 可能为null,在这种情况下,您将获得异常。这可能是你认为你正在防范的,但事实并非如此。如果这真的是你想要的,你需要这样的东西:
"Some Text" + System.Environment.NewLine +
(varOne != null ? varOne.ToString() : string.Empty) + System.Environment.NewLine +
varTwo.ToString()...
这检查varOne不为null,如果不是则使用varOne.ToString,如果是则返回string.Empty。
请注意,我已经避免了这种编码风格的整个问题而不是使用StringBuilder,因为这实际上并不是问题的一部分。
答案 4 :(得分:0)
现在答案已经改变了。你可以:
"Some Text" + System.Environment.NewLine +
// no need to coalesce because concatenating nulls are ignored
varOne?.ToString()
System.Environment.NewLine + varTwo.ToString()
甚至
$"Some Text{System.Environment.NewLine}{varOne}{System.Environment.NewLine}{varTwo}"
// If you're not writing to a system-dependent file, \r\n will also work fine:
$"Some Text\r\n{varOne}\r\n{varTwo}"