使用空合并运算符的字符串串联

本文关键字:字符串 运算符 合并 | 更新日期: 2023-09-27 18:18:58

>我试图构建如下所示的字符串,我注意到在使用 ?? 运算符后它被切断了,无论以前的值是否为 null。

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

字符串包含的所有内容(无论值如何(都取决于 varOne(一些文本 + 换行符 + varOne(,除非我删除 ?? 运算符。环顾四周后,我发现这不是执行此操作的首选方法,我可能应该使用字符串生成器,但我只是好奇为什么会发生这种情况?

使用空合并运算符的字符串串联

看看??运算符(C# 参考(

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

这意味着,如果 ?? 之前的东西为 null,则只分配 之后的东西。

所以

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

sTADA

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

sNormal也会TADA

尝试:

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

varOne.ToString()永远不会null。假设我们有a ?? b + c + d ?? n,如果a != null整个事情都向a而不是a + (d ?? n)(因为运算符优先级(

?? 运算符的意思是"如果这个运算符前面的东西不为 null,就使用它,否则使用这个运算符后面的东西"。

您可能会感到困惑的是,什么构成了"此运算符之前的事情"。在您的情况下,这是整个:

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

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

现在,varOne 可能为空,在这种情况下,你会得到一个异常。这可能是你认为你正在防范的,但事实并非如此。如果这真的是你想要的,你需要这样的东西:

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

这将检查 varOne 是否不为空,如果不是,则使用 varOne.ToString,并回退到字符串。如果是,则为空。

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

如今,答案已经改变。您可以:

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