如何在C#中附加空字符串?

时间:2011-10-31 12:10:43

标签: c# .net string null

我很惊讶地看到一个字符串初始化为null然后在生产环境中附加了一些内容的示例。它只是闻到了错误。

我确信它会抛出一个空对象异常但是这个大大减少的例子也有效:

string sample = null;
sample += "test";
// sample equals "test"

* 注意我发现的原始代码将字符串属性设置为null并在其他地方附加到它,因此涉及编译器在编译时优化掉null的答案是无关紧要的。

有人可以解释为什么这种方法没有错误吗?

随访:

根据Leppie的回答,我使用Reflector来查看string.Concat中的内容。现在很明显为什么要进行转换(根本没有魔法):

public static string Concat(string str0, string str1)
{
    if (IsNullOrEmpty(str0))
    {
        if (IsNullOrEmpty(str1))
        {
            return Empty;
        }
        return str1;
    }
    if (IsNullOrEmpty(str1))
    {
        return str0;
    }
    int length = str0.Length;
    string dest = FastAllocateString(length + str1.Length);
    FillStringChecked(dest, 0, str0);
    FillStringChecked(dest, length, str1);
    return dest;
}

** 注意:我正在研究的具体实现(在Microsoft的.Net库中)不会像C#标准和大多数答案所建议的那样转换为空字符串,而是使用一些测试来快捷的过程。最终的结果和它一样,但是你去了:)

4 个答案:

答案 0 :(得分:47)

字符串的+运算符只是string.Concat的简写,只是在连接之前将null个参数转换为空字符串。

<强>更新

string.Concat的通用版本:

public static string Concat(params string[] values)
{
    int num = 0;
    if (values == null)
    {
        throw new ArgumentNullException("values");
    }
    string[] array = new string[values.Length];
    for (int i = 0; i < values.Length; i++)
    {
        string text = values[i];
        array[i] = ((text == null) ? string.Empty : text);
        num += array[i].Length;
        if (num < 0)
        {
            throw new OutOfMemoryException();
        }
    }
    return string.ConcatArray(array, num);
}

答案 1 :(得分:7)

相关引文应为ECMA-334§14.7.4:

  

字符串连接:

string operator +(string x, string y);
string operator +(string x, object y);
string operator +(object x, string y);  
     

二进制+运算符在一个或多个时执行字符串连接   两个操作数都是string类型。 如果是字符串的操作数   连接是null,空字符串被替换。否则,任何   非字符串操作数转换为其字符串表示形式   调用从类型ToString继承的虚拟object方法。如果   ToString返回null,替换为空字符串。

答案 2 :(得分:3)

这是因为

  

在字符串连接操作中,C#编译器处理null   字符串与空字符串相同,但不转换该值   原始的空字符串。

来自How to: Concatenate Multiple Strings (C# Programming Guide)

  

binary +运算符在一个或两个时执行字符串连接   操作数是字符串类型。如果字符串连接的操作数是   null,替换空字符串。否则,任何非字符串   通过调用,将参数转换为其字符串表示形式   从类型对象继承的虚拟ToString方法。如果ToString   返回null,替换为空字符串。

来自Addition operator

答案 3 :(得分:1)

以下是您的代码编译为

的内容
string sample = null;
sample += "test";

编译为此IL代码:

.entrypoint
  // Code size       16 (0x10)
  .maxstack  2
  .locals init ([0] string sample)
  IL_0000:  nop
  IL_0001:  ldnull
  IL_0002:  stloc.0
  IL_0003:  ldloc.0
  IL_0004:  ldstr      "test"
  IL_0009:  call       string [mscorlib]System.String::Concat(string,
                                                              string)
  IL_000e:  stloc.0
  IL_000f:  ret

String.Concat处理NULL字符串。