C # IComparer <T>стандартный вопрос об использовании - PullRequest
4 голосов
/ 22 июля 2010

У меня есть вопрос, является ли это стандартом для использования IComparer в C #. Скажем, у меня есть ситуация, в которой есть три объекта Person: P1, P2 и P3. Скажем, я вызываю метод Compare, передавая P1 и P2, и результат равен 0. Это означает, что два человека должны быть отнесены к категории равных. Теперь скажите, что я вызываю метод Compare, передавая P2 и P3, и результат для этого также равен 0. Опять же, это означает, что два человека равны. Логически можно предположить, что P1 и P3 также равны; однако метод Compare может быть реализован, однако кто-то решит его реализовать. Так является ли это стандартом для его реализации таким образом, чтобы P1 и P3 также возвращали 0 в этом случае?

Вот код того, что я спрашиваю:

// Assume these are initialized properly
Person p1 = null, p2 = null, p3 = null;
IComparer<Person> comparer = null;

// Compare person 1 to person 2 and result is 0
Debug.Assert(comparer.Compare(p1, p2) == 0);

// Compare person 2 to person 3 and result is 0
Debug.Assert(comparer.Compare(p2, p3) == 0);

// Would this be a fair assumption that person 1 and person 3 would also be 0?
Debug.Assert(comparer.Compare(p1, p3) == 0);

Ответы [ 4 ]

4 голосов
/ 22 июля 2010

Это не имеет ничего общего с C #, это простое математическое правило: Транзитивность: http://en.wikipedia.org/wiki/Transitive_relation

Итак, да, вкратце.

--- Добавлена ​​информация из-за комментария ---

Если вы идете и читаете документацию по IComparer: http://msdn.microsoft.com/en-us/library/system.collections.icomparer.compare.aspx

вы увидите, что:

Compares two objects and returns a value indicating whether one is less than, 
equal to, or greater than the other.

Другими словами, это означает, что при сравнении объектов «a» и «b» вы всегда должны получать один и тот же результат при многократном вызове метода Compare. Если это не так, это означает, что вы получите неопределенное поведение, и будет невозможно полагаться на эту функцию для выполнения какой-либо сортировки или сравнения.

Таким образом, при правильной реализации этого метода применяется правило Транзитивности, и вы можете без каких-либо сомнений сказать, что a == c.

Я надеюсь, что проясните ваш вопрос о проблеме реализации.

3 голосов
/ 22 июля 2010

Да, это будет стандартом.Для IComparable явно указано:

Если A.CompareTo (B) возвращает ноль, а B.CompareTo (C) возвращает ноль, то A.CompareTo (C) требуется для возврата ноля.

Я не могу найти ничего в официальной документации, которая выходит прямо и утверждает то же самое для ICompare, но я думаю, что можно с уверенностью предположить, что то же самое верно.

3 голосов
/ 22 июля 2010

Это часть контракта интерфейса, что если a == b и b == c, то a == c (переходное свойство равенства).Это не применяется нигде в коде, но требуется для правильной работы.

2 голосов
/ 22 июля 2010

Равенство транзитивно, так что да, вы должны принять это и развивать IComparer с учетом этого.

транзитивность

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...