0

昨日、ここに質問への回答を投稿していたとき、どのように問題が発生しString.Equals==状況によって動作が異なりました。

結論String.Equals==行動が欲しい。

bool result = false;

    object obj = "String"; 
    string str2 = "String";
    string str3 = typeof(string).Name;
    string str4 = "String";
    object obj2 = str3; 

    // obj, str2, str4 references are same.
    // obj is object type and others are string type

    // Comparision between object obj and string str2 -- Com 1
    result = String.Equals(obj, str2);// true
    result = String.ReferenceEquals(obj, str2); // true
    result = (obj == str2);// true

    // Comparision between object obj and string str3 -- Com 2
    result = String.Equals(obj, str3);// true
    result = String.ReferenceEquals(obj, str3); // false
    result = (obj == str3);// false

    // Comparision between object obj and string str4 -- Com 3
    result = String.Equals(obj, str4);// true
    result = String.ReferenceEquals(obj, str4); // true
    result = (obj == str4);// true

    // Comparision between string str2 and string str3 -- Com 4
    result = String.Equals(str2, str3);// true
    result = String.ReferenceEquals(str2, str3); // false
    result = (str2 == str3);// true

    // Comparision between string str2 and string str4 -- Com 5
    result = String.Equals(str2, str4);// true
    result = String.ReferenceEquals(str2, str4); // true
    result = (str2 == str4);// true

    // Comparision between string str3 and string str4 -- Com 6
    result = String.Equals(str3, str4);// true
    result = String.ReferenceEquals(str3, str4); // false
    result = (str3 == str4);// true

    // Comparision between object obj and object obj2 -- Com 7
    result = String.Equals(obj, obj2);// true
    result = String.ReferenceEquals(obj, obj2); // false
    result = (obj == obj2);// false

時計も見る

obj     "String" {1#}   object {string}
str2    "String" {1#}   string
str3    "String" {6#}   string
str4    "String" {1#}   string
obj2    "String" {6#}   object {string}

ここここの記事を読んでください

Com1、Com2、Com3、Com4、Com5、および Com6 の動作が異なるのはなぜですか?

4

2 に答える 2

2

この==演算子は、stringsおよび他のすべての参照タイプに対して異なる動作をします。の両方のオペランドが で==あるstring場合、String.Equals比較が使用されます。それ以外の場合==は同等ですObject.ReferenceEquals

C# == Operatorのドキュメントから:

定義済みの値の型の場合、等価演算子 (==) は、オペランドの値が等しい場合は true を返し、そうでない場合は false を返します。文字列以外の参照型の場合、2 つのオペランドが同じオブジェクトを参照している場合、== は true を返します。文字列型の場合、== は文字列の値を比較します。

あなたが見ている他の効果はstring interingです。"String"コード内のリテラル値への参照は 1 つだけです。あなたのコードは以下と同等です: obj = str2 = str4 = "String". obj、str2、および str4 はすべて、基になる同じ文字列への参照です。str3 は実行時に生成されるため、同じ値の "String" を持つ別の文字列に設定されます。

要約する:

  1. com1: 結果 = (obj == str2);// true
    • 比較objectstringて、参照の等価性チェックを実行します
    • obj と str2 は同じ参照を指しているため、結果は true です
  2. 結果 = (obj == str3);// false
    • 比較objectstringて、参照の等価性チェックを実行します
    • obj と str3 は異なる参照を指しているため、結果は false です
  3. 結果 = (obj == str4);// true
    • 比較objectstringて、参照の等価性チェックを実行します
    • obj と str4 は同じ参照を指しているため、結果は true です
  4. 結果 = (str2 == str3);// true
    • 比較stringstringて、文字列値チェックを実行します
    • str2 と str3 はどちらも「文字列」なので、結果は true です
  5. 結果 = (str2 == str4);// true
    • 比較stringstringて、文字列値チェックを実行します
    • str2 と str4 はどちらも「文字列」なので、結果は true です
  6. 結果 = (str3 == str4);// true
    • 比較stringstringて、文字列値チェックを実行します
    • str3 と str4 はどちらも「文字列」なので、結果は true です
  7. result = (obj == obj2);// false - 比較objectobject、参照の等価性チェックを実行します - obj と obj2 は異なる参照を指しているため、結果は false です

実行する比較のタイプは==コンパイル時に選択されるため、オペランドの静的タイプに基づいていることに注意してください。コンパイラは、obj と obj2 が常に文字列を指すことを知りません。

于 2013-02-27T06:08:09.297 に答える
0

Equals参照型の参照と値型の値を比較します。String値型のように動作する参照型です。String大量のデータを格納できるため、ヒープに格納する必要がありますが、不変であり、他の値型と同じように動作します。

上のEqualsメソッドStringは、文字列の値を他のオブジェクト(である必要がありますString)と比較します。

ReferenceEquals2つの参照型が同じインスタンスであるかどうかを判別します。sは参照型ですが不変であるためString、同じ文字列リテラルを異なる文字列で参照できるようにインターンされています。

最後に、等式演算子はStringsの値が等しいかどうかをチェックします。の場合

typeof(string).Name == (object)"String"

false左側のオペランドは実際には文字列型定義に埋め込まれた定数であり、文字列リテラルへの同じ参照を共有しないため、結果が返されます。右側のオペランドはボックス化されているため、それらの参照が比較されます。

于 2013-02-27T05:38:32.060 に答える