1

私は簡単なテストを行いました:

     object t = 3;
     object aa = 3;
#1   Console.WriteLine(t.Equals(aa));  
#2   Console.WriteLine(t.Equals(3));  
#3   Console.WriteLine(3.Equals(aa));  

それらはすべて真実です(それが実際の私の問題です)。

を見てobject 、これは使用される関数です:

 public virtual bool Equals(object obj);

イコールは仮想です。したがって、オーバーライドできます。

しかし、ポリモーフィックな動作は見られません。これは単なるボックス化された値です。

  • 1行目についてt.Equals(aa)

    参照型は静的型-オブジェクトです。

    だから私はそれが呼ばれるべきだと思ったObject.Equals:これは参照が異なること を意味し、最初の答えはそうであるべきであることを意味するFalse(そして私はおそらくここで間違っている)。何故ですか?

  • 2行目についてt.Equals(3)

    繰り返しますが、t's静的型はオブジェクトです。Object.Equals実行中です。どうしてtrueですか?

  • 3行目について3.Equals(aa)

    public override bool Equals(object obj);静的型はintなので、実行中だと思います。paramタイプはobjectです。しかし、なぜそれをするtrueのですか?値のボックスを解除しますか?

何かが、どういうわけか私の通知なしにオブジェクトの箱を開けているようです:-(

4

3 に答える 3

8

ObjectsEqualsメソッドは多態性であるため、のようなサブタイプでオーバーライドできますintInt32.Equalsは、このメソッドをオーバーライドして、現在のオブジェクトとその引数の間の値の比較を行います。ボックスが解除されると引数は等しいため、trueを返します。

Int32.Equals-bool Equals(object)との2つのオーバーロードがありbool Equals(int)ます。オーバーbool Equals(object)ロードは、からオーバーライドされたものobjectです。tおよびaaは参照であるためobject、これは例1および2で呼び出されるメソッドです。

aa例3では、がであるために呼び出されるのは依然としてこのオーバーロードでありobject、したがってこれが唯一の有効なオーバーロードです。

演算子は静的であり、==引数のタイプに基づいて静的に解決さobjectれます。どちらも例にあります。参照を比較するための==演算子object。この場合、2つの別々のボックス化されたintに対してfalseを返します。

于 2013-02-16T21:43:53.307 に答える
5

仮想メソッドObject.Equalsが呼び出されていますが、仮想メソッドの動作方法により、Int32.Equals代わりにメソッドが呼び出されint、参照ではなく値が比較されます。

仮想メソッドは実行時にバインドされます。つまり、コンパイル時ではなく、実行時に適切な方法を選択します。この場合、Object.Equalsはコンパイルされたコードに含まれているものですが、sを比較しているため、実行時intに選択Int32.Equalsします。これは、v-tablesと呼ばれるものを使用して実現されます(これについて詳しく知りたい場合に備えて)。

これはこのように動作することになっていることを覚えておいてくださいEquals。本当に参照の同等性が必要な場合は、を使用できますReferenceEquals

これはボクシングとは何の関係もないことに注意してください。たとえばstring、、またはカスタムクラスでも同じ動作が得られます。

于 2013-02-16T21:46:43.990 に答える
0

あなたがあなたの質問に書いたように、次のアサートはすべて合格します

[Test] 
public void EqualityOnInts()
{
    object a = 1;
    object b = 1;

    Assert.AreEqual(a, b);
    Assert.IsTrue(1.Equals(a));
    Assert.IsTrue(b.Equals(1));
}

インスタンス化する場合は、値1aの新しいintegerオブジェクトを作成します。onのEqualsメソッドを呼び出すと、のメソッドaが呼び出されます。また、Int32`を実行する場合。EqualsInt32a.GetType() it will return

Equals実装はInt32値が等しいかどうかをチェックし、別のオブジェクト参照を気にしないため、結果は「true」になります。

于 2013-02-16T22:10:10.130 に答える