IEqualityComparer.Equals при использовании с IEnumerable.Contains — это значение x или y в списке?
-
09-09-2019 - |
Вопрос
IEnumberable имеет метод расширения contains<T>, который принимает два параметра.Первый параметр — это значение, которое нужно проверить, а второй — реализация IEqualityComparer.Глядя на IEqualityComparer.Equals, он принимает два параметра с именами x и y для сравнения первого и второго объектов.
Мой вопрос: X или Y — это значение из IEnumerable?
Пример
List<string> test = new List<String() { "a", "b", "c" };
test.Contains("d", myComparer);
Когда он вызовет метод Equals для первого значения, будет ли оно равно («A», «D») или Equals («D», «A»)?
Решение
Это не должно иметь значения — равенство должно быть симметричным.Из документов для IEqualityComparer<T>.Equals
:
Метод равных является рефлексивным, симметричным и переходным.То есть он возвращает истинность, если используется для сравнения объекта с собой;Верно для двух объектов x и y, если это правда для Y и X;и верно для двух объектов x и z, если это верно для x и y, а также верно для Y и z.
Я не верю в использование Enumerable.Contains
четко определен, т.е.это может измениться в будущей версии.Если вы просто заставите свой компаратор равенства подчиняться документации по интерфейсу, все будет в порядке.
Другие советы
Для полноты отраженный код IEnumberable показывает, что он находится слева (см. ниже).Однако не обещано, что это когда-либо изменится, поэтому его использование сопряжено с риском.
public static bool Contains<TSource>(this IEnumerable<TSource> source, TSource value, IEqualityComparer<TSource> comparer)
{
if (comparer == null)
{
comparer = EqualityComparer<TSource>.Default;
}
if (source == null)
{
throw Error.ArgumentNull("source");
}
foreach (TSource local in source)
{
if (comparer.Equals(local, value))
{
return true;
}
}
return false;
}