2017-08-31 5 views
1

私は文字列インターンを理解しようとしています。学習以外の真の目的ではありません。私がでてるのはここ文字列インターンとreferenceEquals

です:

文字列は不変と参照型です。この不変性により、文字列のインターンを行うことができます。

文字列インターンなしでは、2つの文字列はヒープ上の2つの文字列になります。

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

をインターンプロセスので、私はそれを理解して、ハッシュテーブル内の文字列を検索し、それを追加していないが場合。さらにインターンシングすると文字列が検索され、見つかった場合は参照がハッシュテーブルの同じ場所を指すように変更されます。

これは比較のスピードを上げるでしょうか?これは、各文字が一致するかどうかを確認する必要がないため、両方の文字列が同じ場所を指しているかどうかを確認するだけです。 (私がこれがどのように機能するかを理解するまでは、今のところ実際にインターンをするというオーバーヘッドを無視しよう)。

私は何を得ていないのですか。なぜ最初のコードブロックが真で、偽でないのですか?

+4

すべての文字列定数は、コンパイラによってインターンされます。 'Object.ReferenceEquals(" foo "、" 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は偽であるべきだと言った!それは私を投げた! – Stuart

+0

はい、それは奇妙です。文字列で 'ReferenceEquals'を使うべきではありません。 – mjwills

+1

@Stuart:あなたの質問を編集して本の名前と版を含めてください。将来の学習者は避けるべきことを知っています。 :-P –

関連する問題