为什么一些相同的字符串不在.NET中实现?

时间:2016-01-11 19:23:55

标签: c# .net string

sort(-rnorm(1000), decreasing = T)[1:300]

字符串s5和s6都具有与s1相同的值(" test")。基于字符串实习概念,这两个语句必须已评估为true。有人可以解释为什么s5没有与s1相同的参考文献吗?

5 个答案:

答案 0 :(得分:8)

对于false对不是字符串文字的ReferenceEquals个对象的string调用,您应该True

基本上,最后一行按巧合打印var s1 = Console.ReadLine(); var s2 = s1+""; var s3 = ""+s1; Console.WriteLine( "{0} {1} {2}" , object.ReferenceEquals(s1, s2) , object.ReferenceEquals(s1, s3) , object.ReferenceEquals(s2, s3) ); :当您传递空字符串进行字符串连接时,库优化会识别这一点,并返回原始字符串。这与实习没有任何关系,因为从控制台读取的字符串或以任何其他方式构造的字符串也会发生同样的事情:

True True True

以上打印

Reverse

Demo.

答案 1 :(得分:2)

CLR不会实习所有字符串。默认情况下,所有string个文字都是实体。但是,以下内容:

Console.WriteLine("{0} ", object.ReferenceEquals(s1, s6)); //True

返回true,因为此处的行:

string s6 = s1.Substring(0,4)+"";  

有效优化以返回相同的参考。碰巧(很可能)被拘禁,但这是巧合。如果您想查看字符串是否被实习,则应使用String.IsInterned()

如果要在运行时实习字符串,可以使用String.Intern并存储引用,具体取决于此处的MSDN文档:String.Intern Method (String)。但是,我强烈建议您不要使用此方法,除非您有充分的理由这样做:它具有性能考虑因素和可能不需要的副作用(例如,已被实习的字符串无法进行垃圾回收)。

答案 2 :(得分:1)

Substring方法非常智能,可以在请求的子字符串完全是原始字符串的情况下返回原始字符串。链接到@ DanielA.White在评论中找到的参考源。因此s1.Substring(0,4)s1的长度为4时返回s1。显然,+运算符具有类似的优化,以便

string s6 = s1.Substring(0,4)+"";

在功能上等同于:

string s6 = s1;

答案 3 :(得分:1)

.NET 中的字符串可以实习。在任何地方都不能说2个相同的字符串应该是相同的字符串实例。通常,编译器将实习相同的字符串文字,但对于所有字符串都不是这样,对于在运行时动态创建的字符串肯定不是这样。

答案 4 :(得分:1)

来自object.ReferenceEquals here的msdn文档:

比较字符串时。如果objA和objB是字符串,则如果字符串是interned,则ReferenceEquals方法返回true。它不执行值相等的测试。在以下示例中,s1和s2相等,因为它们是两个实例但是,s3和s4不相等,因为尽管它们具有相同的字符串值,但该字符串不会被实现。

using System;

public class Example
{
   public static void Main()
   {
      String s1 = "String1";
      String s2 = "String1";
      Console.WriteLine("s1 = s2: {0}", Object.ReferenceEquals(s1, s2));
      Console.WriteLine("{0} interned: {1}", s1, 
                        String.IsNullOrEmpty(String.IsInterned(s1)) ? "No" : "Yes");

      String suffix = "A";
      String s3 = "String" + suffix;
      String s4 = "String" + suffix;
      Console.WriteLine("s3 = s4: {0}", Object.ReferenceEquals(s3, s4));
      Console.WriteLine("{0} interned: {1}", s3, 
                        String.IsNullOrEmpty(String.IsInterned(s3)) ? "No" : "Yes");
   }
}
// The example displays the following output:
//       s1 = s2: True
//       String1 interned: Yes
//       s3 = s4: False
//       StringA interned: No
相关问题