【问题标题】:string interning and referenceEquals字符串实习和referenceEquals
【发布时间】:2017-08-31 11:59:47
【问题描述】:

我正在尝试理解字符串实习。不是为了学习以外的任何实际目的。

这是我所在的位置:

字符串是不可变的并且是引用类型。正是这种不变性让我们能够进行字符串实习。

如果没有字符串实习,这两个字符串将是堆上的两个字符串。

例如

private static void Main()
{
   var a = "foo";
   var b = "foo";
   ReferenceEquals(a, b); // would expect this to be false...
}

我希望ReferenceEquals 是错误的。虽然不是真的。我认为要让它成为现实,我必须这样做:

private static void Main()
{
   var a = "foo";
   var b = "foo";
   ReferenceEquals(a, b); // false??

   string.Intern(a);
   string.Intern(b);
   ReferenceEquals(a, b); // true?
}

据我了解,由于实习过程会在哈希表中查找字符串,如果不存在则添加它。在进一步的实习中,它会查找字符串,如果找到,则将引用更改为指向哈希表中的相同位置。

这应该加快比较?因为它不需要检查每个字符是否匹配,只需检查两个字符串是否指向同一位置。 (让我们暂时忽略实际实习的开销,直到我了解它是如何工作的)。

所以我没有得到什么。为什么第一个代码块返回的是真而不是假?

【问题讨论】:

  • 所有字符串常量都由编译器执行。尝试 Object.ReferenceEquals("foo", "food".Substring(0, 3))Object.ReferenceEquals("foo", String.Intern("food".Substring(0, 3)))

标签: c# string string-interning


【解决方案1】:

这是因为 "foo" 被拘留。

static void Main(string[] args)
{
    var a = "foo";
    var b = "foo";
    Console.WriteLine(string.IsInterned(a));

    Console.WriteLine(ReferenceEquals(a, b));
    Console.ReadLine();
}

编译器将实习生所有文字/常量by default

【讨论】:

  • 谢谢,我不知道文字/常量是默认的。我正在阅读的书给出了使用 2 个常量的示例,并说 ReferenceEquals 应该是错误的!这把我扔了!
  • 是的,这很奇怪。你不应该在字符串中使用ReferenceEquals
  • @Stuart:随时编辑您的问题以包括书名和版本,以便未来的学习者知道要避免什么。 :-P
猜你喜欢
  • 2011-02-11
  • 1970-01-01
  • 1970-01-01
  • 2017-12-23
  • 2011-04-22
  • 2013-03-10
  • 1970-01-01
  • 2010-09-23
  • 2015-02-26
相关资源
最近更新 更多