0
        string s1 = "hi";
        string s2 = "hi";
        bool x = (s1 == s2);
        Console.WriteLine(bool.Parse(""+x)); //printed as true and my point of interest
        x = s1.Equals(s2);
        Console.WriteLine(bool.Parse("" + x));//printed as true
        s1 = s2;
        x = (s1 == s2);
        Console.WriteLine(bool.Parse("" + x));//printed as true
        x = s1.Equals(s2);
        Console.WriteLine(bool.Parse("" + x));//printed as true  

参照を比較するためs1==s2、false として返される必要があります。しかし、出力はtrueになります。文字列のみの場合、これを観察します。これが他のクラスのオブジェクトに対して行われると、正しく false と評価されます。この例外的な動作が文字列で見られるのはなぜですか?

4

3 に答える 3

3

ここでは 2 つのことが行われています。

1 つ目は、文字列型が == 演算子をオーバーロードすることです。== 演算子の参照比較は、デフォルトの動作にすぎません。より良いセマンティクスを得るために、どの型でもその演算子をオーバーロードできます。参照の等価性を保証する場合は、ReferenceEquals()メソッドを使用します。

2 つ目は、 interningと呼ばれるもので、同じ値を持つ 2 つの異なる文字列変数が同じオブジェクトを参照できるようにします。インターンとは、オーバーロードされた == 演算子がなくても、「hi」リテラルが両方の変数に対してインターンされている場合でも、== と ReferenceEquals() の比較が true を返す可能性があることを意味します。

于 2012-12-05T17:35:13.703 に答える
2

s1==s2 は参照を比較するため

それは誤った仮定です。==演算子をオーバーロードして、必要なことを行うことができます。

独自のクラスに対してオーバーロードする方法は次のとおりですString

public class Foo
{
    public int Value { get; set; }
    public static bool operator ==(Foo first, Foo second)
    {
        return first.Value == second.Value;
    }
}
于 2012-12-05T17:33:48.850 に答える
2

MSDN 文字列

文字列は参照型ですが、等値演算子 (== および !=) は、参照 (7.9.7 文字列等値演算子) ではなく、文字列オブジェクトの値を比較するために定義されています。これにより、文字列が等しいかどうかのテストがより直感的になります。

于 2012-12-05T17:34:20.643 に答える