2009-04-15 1 views
2

IEnumberable имеет метод расширения Содержит <T>, который принимает два параметра. Первым параметром является значение для проверки, а второе - реализация IEqualityComparer. Глядя на IEqualityComparer.Equals, требуется два параметра с именем x и y для сравнения первого и второго объектов.IEqualityComparer.Equals при использовании с IEnumerable.Contains является x или y значением в списке?

Мой вопрос X или Y значение из IEnumerable?

Пример

List<string> test = new List<String() { "a", "b", "c" }; 
test.Contains("d", myComparer); 

Когда вызовы метода Equals для первого значения это будет Равно ("а", "г") или равно ("d", "а") ?

ответ

3

Не имеет значения - равенство должно быть симметричным. Из документов для IEqualityComparer<T>.Equals:

Равно метод является рефлексивный, симметрично и транзитивно. То есть, возвращает true, если используется для сравнения объекта с самим собой; true для двух объектов x и y, если это верно для y и x; и true для двух объектов x и z, если это верно для x и y, а также истинно для y и z.

Я не считаю, что использование в Enumerable.Contains четко определено, то есть оно может измениться в будущей версии. Если вы просто сделаете свой сопоставитель по равенству, соблюдайте документацию по интерфейсу, все будет в порядке.

+0

Он по-прежнему всегда меня забавляет, что IComparer * не * должен быть транзитивным ... и в самом деле, не для строки –

1

Для полноты отраженный код 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; 
}