2009-10-19 2 views
1

Точно какие методы в классе несут ответственность за List<T>Contains()?Содержит() метод списка <T>

Я перегрузил == в своем классе. Но, похоже, это не имеет никакого эффекта.

+0

Некоторые хорошие ответы здесь. Почему бы не принять один ... – Vaccano

+0

Я забыл принять. – anonymous

ответ

11

Он просто позвонит Equals() - это все, что нужно переопределить (или нет, если вы довольны сравнительными сравнениями идентичности). Если тип реализует IEquatable<T>, тогда эта реализация будет использоваться вместо общего Equals(object).

В частности, из документации для List<T>.Contains:

Этот метод определяет равенство, используя равенство по умолчанию компаратор EqualityComparer(T).Default для T, то типа значений в списке.

И от EqualityComparer<T>.Default: реализует

В Default проверяет свойство ли типа T общего интерфейс System.IEquatable(T) и если это так возвращает EqualityComparer(T), который использует эту реализации. В противном случае он возвращает a EqualityComparer(T), который использует переопределения Object.Equals и Object.GetHashCode предоставленный T.

Я не верю, что он будет использовать GetHashCode.

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>(); 
} 
2

из принципов .NET - если вы реализуете == всегда обеспечивают реализацию для Object.equals() и = оператор. Причина в том, что операторы не являются частью какого-либо интерфейса, и их использование не допускается в общих реализациях (класс List не может вызывать оператор == на T, потому что нет гарантии, что T будет иметь определенный оператор (см., Например, структуры)).