1

C# で VALUE と REFERENCES を比較する方法はたくさんあることは知っていますが、VALUE または REFERENCE のいずれかを比較しようとすると、どの型が何を実行するのか、まだ少し混乱しています。

文字列の例:

string str = "hello";
string str2 = "hello";

if (str == str2)
{
   Console.WriteLine("Something");
} // Is this a comparison of value?

if (str.Equals(str2))
{
   Console.WriteLine("Something");
} // Is this a comparison of value?

string.ReferenceEquals(str, str2); // Comparison of reference (True)

Console.WriteLine((object)str1 == (object)str2); // Comparison of reference (True)
4

5 に答える 5

4

Equals==サブクラスでオーバーライド/オーバーロードされていない場合、デフォルトで参照によって比較されます。ReferenceEquals常に参照によって比較されます。

==文字列は値の等価性を実装するためにオーバーロードされるため、これを試すために使用するデータ型はわかりにくいものです。また、それらは不変であるため、C# は通常、同じリテラル文字列に対して同じインスタンスを再利用します。あなたのコードでstrstr2、同じオブジェクトになります。

于 2011-10-19T12:43:26.610 に答える
2

@Inerdia は彼の言うことは正しいですが、コード例で行 string.ReferenceEquals(str, str2) が true を返す理由を指摘したいと思います。コンパイル時に両方の文字列を定義しているため、コンパイラはコードを最適化して、両方が文字列の同じインスタンスを指すようにすることができます。文字列は不変であるため、文字列が参照型であっても、コンパイラはこれを実行できることを認識しています。ただし、コードを変更して (以下に示すように) 文字列の 1 つを動的に生成する場合、コンパイラはこの最適化を実行できません。したがって、コードを次のように変更すると、コード例で:

string str = "hello";
string str2 = new StringBuilder().Append("he").Append("llo").ToString(); 

次に、string.ReferenceEquals(str, str2) 行は、今回はコンパイラが同じインスタンス (文字列の参照) を再利用することを認識できないため、false を返します。

于 2011-10-19T12:59:16.020 に答える
1
  1. string.ReferenceEquals(str, str2);
    明らかに参照を比較します。
  2. str.Equals(str2)
    最初に参照を比較しようとします。次に、値による比較を試みます。
  3. str == str2
    Equals と同じです。

文字列を比較する良い方法は、string.Compare を使用することです。大文字と小文字を区別したくない場合は、そのためのパラメーターも用意されています。

于 2011-10-19T12:58:28.227 に答える
0

.net ソースからの抜粋:

public bool Equals(string value)
{
  if (this == null)
    throw new NullReferenceException();
  else if (value == null)
    return false;
  else if (object.ReferenceEquals((object) this, (object) value))
    return true;
  else
    return string.EqualsHelper(this, value);
}

したがって、一般的には最初に参照を比較し、それらが一致しない場合は値を比較します。

于 2011-10-19T12:43:33.367 に答える