2010-07-22 3 views
4

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

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

// 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); 

ответ

3

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

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

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

2

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

Transitivity

4

Это не имеет ничего общего с 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. Если это не так, это означает, что вы получите неопределенное поведение, и будет невозможно полагаться на эту функцию для выполнения любой сортировки или сравнения.

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

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

+0

Я понимаю это, но метод Compare можно реализовать таким образом, чтобы переходное правило не применялось. Метод Compare может возвращать новые Random(). Next(); и тогда переходное правило не будет применяться.Поэтому я спрашиваю, является ли это стандартом для метода Compare, который реализуется там, где это правило применяется. – Nick

+1

Это соглашение, более того, достаточно сильное, чтобы быть контрактом, который должен соблюдаться для правильной работы интерфейса. Неопределенное поведение, если вы не следуете контракту :) – user7116

+0

Действительно смешно. Это как сделать метод: getCurrentTime() {return Time (Random()); }. Это просто не имеет смысла. Метод сравнения должен быть конечным и всегда иметь такое же поведение. В вашем примере это означает, что a.Compare (b) cond возвращает 3 разных результата, если вызвано 3 раза подряд. Я не думаю, что для этого предназначена эта функция. – Sauleil

3

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

Смежные вопросы