ICollection <T>. Содержит пользовательские типы - PullRequest
9 голосов
/ 27 января 2010

Если у меня есть (ссылка - имеет ли это значение?) Тип MyType , который не переопределяет метод Equals , то какая эвристика будет использоваться при определении, если ICollection содержит данный экземпляр типа?

Как лучше всего использовать мою собственную эвристику (например, проверить равенство значения свойства Id )?

Ответы [ 4 ]

8 голосов
/ 27 января 2010

Поскольку ваш тип не переопределяет Equals, будет использоваться реализация Equals по умолчанию, т. Е. Ссылочное равенство. Поэтому Contains будет истинным, если коллекция содержит того самого экземпляра .

Чтобы использовать собственное сравнение, реализуйте IEqualityComparer<T> (например, для сравнения идентификаторов) и передайте экземпляр вашего компаратора в метод Contains. (Предполагается, что вы можете использовать расширения LINQ, поскольку «родной» метод ICollection<T>.Contains не имеет перегрузки IEqualityComparer.)

1 голос
/ 27 января 2010

Это не определено ICollection<T> - разные реализации могут использовать разные методы. От MSDN :

Реализации могут варьироваться в зависимости от того, как они определить равенство объектов; за Например, List<T> использует Comparer<T>.Default, тогда как Dictionary<TKey, TValue> позволяет пользователю указать IComparer<T> реализация использовать для сравнения ключи

В большинстве случаев он просто сравнивает ссылки, но вы должны проверить документацию для конкретного ICollection<T>, который вы используете.

0 голосов
/ 27 января 2010

По данным MSDN:

Реализации могут варьироваться в зависимости от того, как они определить равенство объектов; за Например, List <(Of <(T>)>) использует Comparer <(Of <(T>)>) .. ::. По умолчанию, в то время как словарь <(Of <(TKey, TValue>)>) позволяет пользователю указать IComparer <(Of <(T>)>) реализация использовать для сравнения ключи.

Лучший способ сделать это самостоятельно - использовать перегрузку, которая принимает IEqualityComparer<T>

public class MyComparer : IEqualityComparer<MyType>
{
    public bool Equals(MyType x, MyType y)
    {
        return x.Id == y.Id;
    }

    public int GetHashCode(MyType obj)
    {
        return obj.Id.GetHashCode();
    }
}
0 голосов
/ 27 января 2010

AFAIK, ссылка (адрес в памяти) будет сравниваться ...

Если ссылка вам не подходит, вы можете сравнить идентификатор, как вы упомянули.

...