1

正確には、クラス内のどのメソッドがList<T>Contains()動作を担当していますか?

クラスで==をオーバーロードしました。しかし、効果はないようです。

4

3 に答える 3

11

呼び出すだけですEquals()-オーバーライドする必要があるのはそれだけです(または、参照IDの比較に満足している場合はそうではありません)。タイプが実装する場合、IEquatable<T>その実装は一般的なものよりも優先して使用されEquals(object)ます。

特に、以下のドキュメントからList<T>.Contains

このメソッドは、リスト内の値のタイプであるのデフォルトの等式比較子 EqualityComparer(T).Defaultを使用して等式を判別します。T

そしてからEqualityComparer<T>.Default

Defaultプロパティは、typeがジェネリックインターフェイスを実装しているかどうかをチェックし、実装している場合は、その実装を使用するを返し Tます 。それ以外の場合は、のオーバーライドを使用し、によって 提供されるを返します。System.IEquatable(T)EqualityComparer(T)EqualityComparer(T)Object.EqualsObject.GetHashCodeT

私はそれがGetHashCodeまったく使用されるとは思わない。

于 2009-10-19T15:32:24.353 に答える
2

.NET ガイドラインから - == を実装する場合は、常に object.Equals() と != 演算子の実装を提供してください。その理由は、演算子はインターフェースの一部ではなく、一般的な実装では使用できないためです (T に演算子が定義されているという保証がないため、List クラスは T で == 演算子を呼び出すことはできません (たとえば、構造体を参照)。 )。

于 2009-10-19T15:53:43.670 に答える
1

呼び出すObject.Equals()か、実装している場合は次のいずれかを行いIEquatable<T>.Equals()ます。

private static EqualityComparer<T> CreateComparer()
{
    Type c = typeof(T);
    if (c == typeof(byte))
    {
        return (EqualityComparer<T>) new ByteEqualityComparer();
    }
    if (typeof(IEquatable<T>).IsAssignableFrom(c))
    {
        return (EqualityComparer<T>) typeof(GenericEqualityComparer<int>).TypeHandle.CreateInstanceForAnotherGenericParameter(c);
    }
    if (c.IsGenericType && (c.GetGenericTypeDefinition() == typeof(Nullable<>)))
    {
        Type type2 = c.GetGenericArguments()[0];
        if (typeof(IEquatable<>).MakeGenericType(new Type[] { type2 }).IsAssignableFrom(type2))
        {
            return (EqualityComparer<T>) typeof(NullableEqualityComparer<int>).TypeHandle.CreateInstanceForAnotherGenericParameter(type2);
        }
    }
    return new ObjectEqualityComparer<T>();
}
于 2009-10-19T15:37:07.930 に答える