2017-08-31 40 views
1

我想了解字符串interning。除了學習之外,不是爲了任何真正的目的字符串interning和referenceEquals

下面是我在哪裏:

字符串是不可變的引用類型。它的這種不變性使我們能夠進行串聯實習。

如果沒有字串實習,則兩個字符串將是堆上的兩個字符串。

例如

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

由於實習過程中,我的理解是,查找在哈希表中的字符串,如果它不存在它增加了它。在進一步的實習中,它會查找字符串,如果它找到它,那麼它將引用更改爲指向哈希表中的相同位置。

這應該加快比較?因爲它不需要檢查每個字符是否匹配,並且可以檢查兩個字符串是否指向相同的位置。 (讓我們忽略實際實習的開銷,直到我明白這是如何工作的)。

所以我沒有得到什麼。爲什麼第一個代碼塊返回true而不是false?

+4

所有字符串常量都由編譯器實現。嘗試'Object.ReferenceEquals(「foo」,「food」.Substring(0,3))'Object.ReferenceEquals(「foo」,String.Intern(「food」.Substring(0,3)))''。 –

回答

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

+0

謝謝,我不知道文字/常量是默認實現的。我正在處理的這本書給出了使用2個常量的例子,並說ReferenceEquals應該是false!哪個扔了我! – Stuart

+0

是的,那很奇怪。你不應該在字符串中使用'ReferenceEquals'。 – mjwills

+1

@Stuart:隨時編輯您的問題,以包括本書的名稱和版本,以便將來的學習者知道要避免什麼。 :-P –