212

Foodクラスが の別のインスタンスと等しいときはいつでもテストできるようにしたいFoodList.Contains()後で List に対して使用しますが、そのメソッドを使用したいと考えています。実装するIEquatable<Food>か、単にオーバーライドする必要がありますObject.Equals()か? MSDN から:

このメソッドは、T (リスト内の値の型) に対する IEquatable.Equals メソッドのオブジェクトの実装によって定義されているように、既定の等値比較子を使用して等値を判断します。

では、次の質問は、.NET フレームワークのどの関数/クラスが を利用しているのObject.Equals()かということです。そもそも使うべき?

4

4 に答える 4

245

主な理由はパフォーマンスです。List<T>ジェネリックが .NET 2.0 で導入されたとき、Dictionary<K,V>、 、 などの一連のきちんとしたクラスを追加することができました。これらの構造は、およびHashSet<T>を多用します。しかし、値型の場合、これにはボクシングが必要です。構造体に厳密に型指定されたメソッドを実装できるようにするため、ボックス化は必要ありません。したがって、ジェネリック コレクションで値型を使用すると、パフォーマンスが大幅に向上します。GetHashCodeEqualsIEquatable<T>Equals

参照型はそれほどメリットはありませんが、実装により、頻繁に呼び出される場合に違いを生む可能性IEquatable<T>のあるキャストを回避できます。System.Object

ただし、Jared Parson のブログに記載されているように、標準とオーバーライドを実装する必要があります。Object.EqualsObject.GetHashcode

于 2010-04-29T05:20:43.583 に答える
55

MSDNによると:

を実装する場合は、とIEquatable<T>の基本クラスの実装もオーバーライドし て、その動作が メソッドの動作と一致するようにする必要があります。override を 実行すると、オーバーライドされた実装もクラスの静的メソッドの呼び出しで呼び出されます。これにより、メソッドのすべての呼び出しが一貫した結果を返すことが保証されます。Object.Equals(Object)GetHashCodeIEquatable<T>.EqualsObject.Equals(Object)Equals(System.Object, System.Object)Equals

したがって、クラスの使用方法に応じてどちらかを呼び出すことができることを除いて、2 つの間に実際の機能上の違いはないようです。パフォーマンスの観点からは、ボックス化/ボックス化解除のペナルティがないため、汎用バージョンを使用することをお勧めします。

論理的な観点からは、インターフェイスを実装することもお勧めします。オブジェクトをオーバーライドしても、クラスが実際に同等であることは誰にもわかりません。オーバーライドは、何もしないクラスまたは浅い実装である可能性があります。インターフェイスを使用すると、「ねえ、これは等価チェックに有効です!」と明示的に表示されます。それはちょうど良いデザインです。

于 2010-04-29T05:22:53.860 に答える
33

ジョシュが言ったことを実際の例で拡張します。Joshに+1 - 私は答えに同じことを書こうとしていました。

public abstract class EntityBase : IEquatable<EntityBase>
{
    public EntityBase() { }

    #region IEquatable<EntityBase> Members

    public bool Equals(EntityBase other)
    {
        //Generic implementation of equality using reflection on derived class instance.
        return true;
    }

    public override bool Equals(object obj)
    {
        return this.Equals(obj as EntityBase);
    }

    #endregion
}

public class Author : EntityBase
{
    public Author() { }
}

public class Book : EntityBase
{
    public Book() { }
}

このようにして、すべての派生クラスに対してすぐに使用できる再利用可能な Equals() メソッドがあります。

于 2010-04-29T05:33:54.770 に答える