9

この状況ReferenceEqualsでオブジェクトのメソッドの動作が異なるのはなぜですか?

string a= "fg";
string b= "fg";
Console.WriteLine(object.ReferenceEquals(a, b));

したがって、この状況では結果が得られtrueます。場合によっては、参照ではなく文字列の値を比較します。しかし、私が次のようなものを書くとき:

StringBuilder c = new StringBuilder("fg");
string d = c.ToString();
Console.WriteLine(object.ReferenceEquals(a, d));

この場合false、オブジェクトの参照を比較するため、正常に機能し、結果はです。

4

5 に答える 5

17

"fg"最初の例には、 2つの変数によって参照されるコンパイル時定数があります。これはコンパイル時定数であるため、2つの変数は1つのオブジェクトを参照します。参照は同じです。

この動作の詳細については、文字列インターンのトピックをお読みください。手始めとして、次のことを考慮してください。

たとえば、同じリテラル文字列を複数の変数に割り当てると、ランタイムはインターンプールからリテラル文字列への同じ参照を取得し、それを各変数に割り当てます。

http://msdn.microsoft.com/en-us/library/system.string.intern.aspx

2番目の例では、1つだけがコンパイル時定数であり、もう1つはいくつかの操作の結果です。aまたd、同じオブジェクトを参照しないため、から誤った結果が得られますReferenceEquals

于 2012-02-02T12:54:19.017 に答える
3

どちらの場合も正しく動作しています。

aとが同じ文字列オブジェクトである理由bは、コンパイラが同じ文字列を2回指定したことに気づき、同じ文字列オブジェクトを再利用してとの両方を初期化したためaですb

これは通常、アプリケーションのすべての文字列定数で発生します。

于 2012-02-02T12:54:55.550 に答える
0

同じリテラル( "fg")を参照しているため、両方の文字列は実際には同じものを指します。この記事をご覧ください:http://csharpindepth.com/Articles/General/Strings.aspx(段落「インターニング」)。

よろしく、ピョートル

于 2012-02-02T12:57:14.490 に答える
0

この投稿によると、それはインターンと呼ばれるものと関係があります。aとbは、あなたの場合、同じインスタンスを指す2つの変数です。そのため、ReferenceEqualsはtrueを返します。

于 2012-02-02T12:57:48.877 に答える
0

これは、バージョン4.5を超えるCLRのアセンブリがSystem.Runtime.CompilerServices.CompilationRelaxations Attribute、フラグの値を定義する属性でマークSystem.Runtime.CompilerServices. CompilationRelaxations.NoStringInterningされているためです。これは、パフォーマンスを向上させる目的で実装されました。

4.5未満のCLRバージョンでコードを実行すると、変数abは、値が「fg」のヒープ内のさまざまな文字列オブジェクトを参照し、object.ReferenceEquals(a, b)結果が「False」になります。

CLR 4.5以降object.ReferenceEquals(a, b)、アセンブリをアプリケーションドメインにアップロードするときに「fg」文字列をインターンするため、の比較では結果が「True」になります。これは、ヒープ内の同じ文字列への参照をa意味します。b

于 2020-12-26T20:24:56.360 に答える