2013-06-19 51 views
1

我试图建立一个如下所示的字符串,我注意到它在使用?无论前一个值是否为空,都是如此。与空合并运算符的字符串连接

"Some Text" + System.Environment.NewLine + 
varOne.ToString() ?? string.Empty + System.Environment.NewLine + 
varTwo.ToString()... 

所有的字符串包含(不管值)达到的Varone(某些文本换行+ +的Varone),除非我删除?运营商。看了一下后,我发现这不是这样做的首选方式,我应该使用一个stringbuilder来代替,但我只是好奇为什么发生这种情况?

+0

如果变量'null',调用'ToString'它会抛出。 – Oded

+3

框架中没有从'ToString'返回'null'的类,我怀疑这样做是个好主意。所以'ToString'之后的空合并运算符没有意义。也许这个:'varOne == null? string.Empty + System.Environment.NewLine:varOne.ToString()' –

+0

也许一些额外的括号可能会有所帮助。 '''优先级低于'+'。看看这个:http://msdn.microsoft.com/en-us/library/6a71f45d.aspx – spender

回答

6

看一看?? Operator (C# Reference)

的?运算符称为空合并运算符,用于为可为空的值类型或引用类型定义默认值。它 返回左操作数,如果操作数不为空;否则它会返回右操作数。

这意味着,??之后的东西只会被分配,如果之前的东西是空的。

所以

 string sNull = null; 
     string s = sNull ?? "TADA"; 

sTADA

 string sNull = null; 
     string s = sNull ?? "TADA"; 
     string sNormal = s ?? "NOT TADA"; 

sNormal也将是TADA

+0

谢谢你 – aw04

2

尝试:

"Some Text" + System.Environment.NewLine + 
(varOne == null ? string.Empty : varOne.ToString()) + System.Environment.NewLine + 
varTwo.ToString()... 
+2

如果'varOne'为'null',这会抛出... – Oded

+0

@Ond Duh,你说得对。修正了,谢谢! –

+0

@ X.L.Ant很好的解决方案,谢谢。唯一的原因我没有标记为答案是我想明白为什么它不起作用,不只是代码来解决它:) – aw04

1

varOne.ToString()从未null。而假设我们有a ?? b + c + d ?? n,如果a != null整个事情eveluates到a而不是a + (d ?? n)(因为运营商优先级)

1

的?操作符表示“如果该操作符之前的东西不是空的,则使用它,否则使用该操作符之后的东西”。

你可能会感到困惑的是什么构成“这个运营商之前的事情”。在你的情况下,这是整个:

"Some Text" + System.Environment.NewLine + varOne.ToString() 

这永远不会是空的。即使varOne.ToString()返回null(这将是varOne类中的一个错误,因为ToString()不应该返回null),所以将字符串与null连接的结果是原始字符串。绝对没有上述情况可能导致无效的情况。

现在,varOne可能为空,在这种情况下,您会收到异常。这可能是你认为你所反对的,但事实并非如此。如果这真的是你想要的,你需要这样的事:

"Some Text" + System.Environment.NewLine + 
(varOne != null ? varOne.ToString() : string.Empty) + System.Environment.NewLine + 
varTwo.ToString()... 

这将检查的Varone不为空,使用varOne.ToString如果不是,将回退到的String.Empty,如果它是。

请注意,我避免了这种编码风格与使用StringBuilder的问题,因为这实际上并不是问题的一部分。

+0

这正是我误解,谢谢 – aw04

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}"