Есть ли в IEquatable каскад? - PullRequest
1 голос
/ 05 марта 2012

У меня очень простой вопрос относительно IEquatable. Даны следующие основные классы:

public class Person
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public SalaryInformation AnnualSalaryInformation { get; set; }

    }

    public class SalaryInformation
    {
        public string TaxCode { get; set; }
        public string SalaryBand { get; set; }
        public BankInformation AccountInfo { get; set; }
    }

    public class BankInformation
    {
        public string SortCode { get; set; }
        public string AccountNumber { get; set; }
    }

Если бы я хотел сравнить объекты Person для равенства, как бы я поступил? Если я реализую интерфейс IEquatable в классе Person, будет ли он автоматически каскадироваться к любым объектам в этом классе или мне придется явно реализовывать интерфейс во всех классах?

Если мне нужно реализовать интерфейс для всех классов, есть ли какие-то особые «ошибки», на которые я должен обратить внимание при сравнении экземпляра Person с другим экземпляром Person?

Ответы [ 3 ]

4 голосов
/ 05 марта 2012

Равенство между объектами может принимать разные формы, в зависимости от того, что именно вам нужно.Чтобы ответить на ваш вопрос:

Нет , то, что Person реализует IEquatable, не означает, что SalaryInformation реализует IEquatable.Отношения между Person и SalaryInformation являются композицией, а композиции не заботятся о реализации интерфейса.

Реализация Equals Person, таким образом, зависит от того, когда вы считаете, что два человека одинаковы:

  • Они одинаковы, если у них одинаковые имя и фамилия?
  • Они одинаковы, если у них тоже одинаковые SalaryInformation тоже?

Кроме того, если вы хотите иметь возможность сравнивать объекты на равенство, следует помнить следующее:

  1. Равенство - это отношение эквивалентности, т. Е. Оно
    a.возвратный,
    б.симметричный и
    c.переходный.
  2. Помните, что null не равен ни одному объекту.
  3. Всегда переопределяйте GetHashCode тоже.

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

1 голос
/ 05 марта 2012

Все зависит от вашего собственного определения, когда два Person экземпляра равны! Здесь нет никакого волшебства, и реализация IEquatable на Person никак не каскадируется.

Итак, как вы определяете два экземпляра Person как равные в контексте вашего приложения? Достаточно ли хорошо равенство фамилии и имени? Если это так, то вам следует реализовать IEquatable. Другие альтернативы, которые иногда используются, - это определение равенства на основе некоторого сгенерированного первичного ключа или известной уникальной стоимости, такой как номер национального страхования.

0 голосов
/ 05 марта 2012

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

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

Если вы реализуете Equals и GetHashCode(вам нужны оба), как правило, вы должны стараться включать в сравнение только поля, доступные только для чтения.Помимо этого, вы должны убедиться, что GetHashCode хорошо работает с Equals (например, не возвращает разные значения, если Equals возвращает true) и, конечно, Equals должен быть симметричным.

...