15

重複の可能性:
C# の == 演算子と Equals() メソッドの違い?

平等には 2 つの形式があります。最初は失敗し、2 番目は成功します。

(object)"abc" == (object)"abc"
false

((object)"abc").Equals((object)"abc")
true

以下のリファレンスでは、「C# の等値演算子はポリモーフィックではありません」と記載されています。

ref: c# の文字列等価演算子 ==

ところで:なぜこれが問題なのかはまだわかりません。このようなものかと思いましたが、このテストが成功したからではありません。

    static void Main(string[] args) {
        var o = new classOfT<string>() { val = "abc" };
        Console.WriteLine((object)o.val == "abc");
    }

    public class classOfT<T> {
        public string val { get; set; }
    }

ところで: この質問に対する正確な重複判断には同意しませんが、ねえ。

回答には次のように記載されています。

... String クラスには、 static bool Equals(string a, string b) メソッドと static bool Equals(object a, object b) メソッドの両方が含まれています。違いは、前者は String クラス自体の中で定義され、後者は Object クラス (String の基本クラス) から継承されることです。

これは意味的には理にかなっていますが、OO と C# 言語のより広いコンテキストでは意味がありますか?

なぜ私はその質問に悩まされているのですか? ええと、ちょうどバグを見つけたので、「これを覚えているだけ」ではなく、韻または理由の下でこれを脳内にファイルしたいと思います。カテゴリの前に噛まれました。

アップデート:

現在、(機能的な観点から) プリミティブとポリモーフィズムを扱うという観点からこれについて考えています。私はますます機能的なことをしているので、母国語が私を混乱させたのはおそらくこれが理由です. 私はまだこれについて考え終わっていません (いいえ、私は実用的ではありません。私は言語設計に惹かれています)。全部答えてくれてありがとう!

4

4 に答える 4

3
(object)"abc" 

文字列オブジェクトからオブジェクト参照を作成します。そうすること

(object)"abc" == (object)"abc"

等しくない2つのオブジェクト参照を作成します。

ただし、equalsメソッドを使用すると、格納されている文字列の値が等しいかどうかが確認されます。繰り返しますが、これはすべてのオブジェクトのデフォルトの実装ではなく、Stringオブジェクトの実装です。カスタムオブジェクトの場合、この動作を実現するには、equalsメソッドの独自のカスタム実装を定義する必要があります。

于 2012-10-08T04:25:02.540 に答える
2

コード サンプルは true を返します。

(object)"abc" == (object)"abc"

アプリケーションで false を返すコードとは異なる例を提供したと思います。CLR は、文字列の最適化に文字列インターンを使用します。System.Object にキャストすると、== 演算子が参照を比較し、文字列のインターン機能により、== 演算子は true になります。== 演算子の両側のパラメーターがヒープ上の異なる文字列オブジェクトを参照する場合にのみ、比較は false を返します。

[assembly: CompilationRelaxations(System.Runtime.CompilerServices.CompilationRelaxations.NoStringInterning)]アセンブリが属性でマークされているかどうかを確認します。

于 2012-10-08T05:10:59.743 に答える
1

文字列比較は , 経由String.Compareで行う必要があります

http://blogs.msdn.com/b/abhinaba/archive/2005/10/28/486173.aspx

http://msdn.microsoft.com/en-US/vstudio/aa496123?pull=/library/en-us/dndotnet/html/StringsinNET20.asp

Microsoft は .NET BCL で同じことを何度も行っており、開発者として適応しなければならないことが一般的になっているため、「バグを見つけた」とは思いません。簡単な例は、

var ip1 = IPAddress.Parse("127.0.0.1");
var ip2 = IPAddress.Parse("127.0.0.1");

が見つかりますip1 != ip2が、ip1.Equals(ip2) == true. おすすめの比較方法はIPAddress.Compare(ip1, ip2). とにかく、時々何かを覚えなければなりません。

于 2012-10-13T08:52:59.837 に答える
0

==演算子

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

等しい

「objがStringであり、その値がこのインスタンスと同じである場合はtrueを返し、それ以外の場合はfalseを返す」文字列クラスによってオーバーライドされます。

コードが次のような場合、

var s1= GetString1(); //some string object
var s2= GetString2(); //some string object containing same content as s1

(object)s1 == (object)s2
returns false - because == compares the references of the objects (which will be different if not interned)

((object)s1).Equals((object)s2)
returns true - because Equals will be called between actual strings at run time

しかし、現在の形式では、コードは

(object)"abc" == (object)"abc"
((object)"abc").Equals((object)"abc")

同じ値のリテラル文字列はデフォルトでインターンされ、したがって同じオブジェクトを参照するため、どちらの場合もtrueを返す必要があります(つまり、参照も等しい)

于 2012-10-08T05:34:02.130 に答える