string.Empty vs."" - 这改变了吗?

mut*_*y91 5 c#

根据这个答案,""并且string.Empty略有不同,因为它""创造了一个对象,而string.Empty没有.那个答案对这个问题的投票最多.

但是,这个答案说没有区别.这也是最近的答案.

所以这是在2010年.这是真的吗?做string.Empty""在所有不同,甚至略有?

编辑:这个问题是对相关问题的更新,因为我发现令人困惑的是,尽管对此事进行了一些辩论,但没有提出任何现代答案.

Hen*_*man 6

语言规范(C#4.0)实际上对这个主题保持沉默.

根据CLR通过C#,它完全取决于CLR而不是C#编译器.来自p的相关引用.341:

即使程序集指定了此属性/标志[CompilationRelaxations.NoStringInterning],CLR也可以选择实际执行字符串,但您不应指望这一点.实际上,除非你自己编写了明确调用String的Intern方法的代码,否则你真的不应该编写依赖于字符串实例的代码.

因此,使用""可能会或可能不会创建新的字符串对象.这取决于所使用的CLR(版本).并且编译器也可能折叠常量,在这种情况下"",每个程序集编译单元会花费1个对象,而不是每次出现.

这一切都不对内存使用或速度的任何相关影响,但清晰的指引应该是两者ReferenceEquals(s1, "")ReferenceEquals(s1, String.Empty)应避免.

当然Object.Equals(s1, s2),s1 == s2总是在字符串上工作正常.


Ada*_*dam 0

您可以在String.Empty中直接读到,该字段 ( ) 的值String.Empty是零长度字符串""

您可以通过一个小测试来测试它们是否引用相同的字符串。

void main()
{
    String first = "";
    String second = String.empty;

    bool test = Object.ReferenceEquals(first, second);
}
Run Code Online (Sandbox Code Playgroud)

测试将返回 true,这意味着它们引用同一个对象。

另一个细微的区别是评估""比 稍微更优化和高效String.empty

编辑:

static void Main ( string[] args )
{
    string s1 = "MyTest";
    string s2 = new   StringBuilder().Append("My").Append("Test").ToString();
    string s3 = String.Intern(s2);

    Console.WriteLine((Object)s2 == (Object)s1); // Different references.
    Console.WriteLine((Object)s3 == (Object)s1); // The same reference.
    Console.WriteLine();


    s1 = "";
    s2 = new StringBuilder().Append("").ToString();
    s3 = String.Empty;
    string s4 = String.Intern(s2);

    Console.WriteLine((Object)s2 == (Object)s1); // The same reference.
    Console.WriteLine((Object)s3 == (Object)s1); // The same reference.
    Console.WriteLine((Object)s4 == (Object)s1); // The same reference.
    Console.WriteLine((Object)s4 == (Object)s2); // The same reference.
}
Run Code Online (Sandbox Code Playgroud)

通过 interning 可以很明显地看出字符串文字已经被 interned 了。当stringbuilder创建一个具有相同对象的新 String 对象时,它不会被保留,并且对该对象的引用不相同。但是,当我们String.Intern(s2)该方法返回分配给的相同引用时s1,该引用随后分配给s3

想法

那么为什么这四种情况都返回 true。我知道字符串文字""是被保留的,但为什么不使用相同的方式Stringbuilder附加到新的字符串对象,即使从技术上讲它是一个未被保留的新对象。""""

  • `""` 也使用实习(否则 ReferenceEquals 将返回 false)。因此,也不存在“稍微更优化”的情况。 (3认同)
  • 引入 StringBuilder 只会混淆问题。但这里根本没有“必需的行为”。请参阅我的答案中的引用,RefEquals 仅在您自己 Intern() 时才可靠。 (2认同)