2015-12-17 7 views
0

У меня есть объект под названием User. Вот мой класс:Список не равен, когда он должен

Я создаю ДВУХ ОБЪЕКТОВ, которые являются точно такими же.

Я хочу видеть, если их Равный, однако, я получаю False назад.

User user1 = new User() 
{ 
    Name = "Test User", 
    IdNumber = "1000354", 
    OrgName = "North", 
    AcctCode = "FTW" 
}; 

User user2 = new User() 
{ 
    Name = "Test User", 
    IdNumber = "1000354", 
    OrgName = "North", 
    AcctCode = "FTW" 
}; 

var doesEqual = user1.Equals(user2); 
Console.WriteLine(doesEqual); // Returns FALSE 

У меня также есть TWO-списки, в которых есть те же объекты, кроме одного.

Когда я делаю Except, он не хочет работать правильно и возвращает 131.

List<User> ListOne; // Contains 131 User objects 
List<User> ListTwo; // Contains 130 User objects 
var difference = ListOne.Except(ListTwo); 
Console.WriteLine(difference); // Returns 131 

Что я делаю не так ??

ответ

1

Критерии равенства по умолчанию по умолчанию. Он должен возвращать false.

Вы можете переопределить метод Equals (а затем вам нужно будет реализовать GetHashCode) по любой логике, которую вы хотите.

public override bool Equals(object obj) 
{  

    if(!(obj is User)) 
    { 
     return false; 
    } 

    User user= obj as User; 
    return user.Name == Name && user.IdNumber == IdNumber && user.OrgName == OrgName && user.AcctCode == AcctCode; 
} 

public override int GetHashCode() 
{ 
    return IdNumber.GetHashCode(); 
} 
0

Несмотря на то, что все свойства ваших объектов имеют одинаковое значение, они представляют собой два совершенно разных объекта. Этот user1 содержит ссылку на кучу для объекта с некоторыми значениями. То же самое справедливо и для user2. Говоря это, это две разные ссылки на кучу.

Если вы не переопределите метод Equals, тогда равенство основано на ссылках. Таким образом, объекты разные, даже если они имеют одинаковые значения для всех своих свойств.

0

Они не равны, потому что User является классом (т. Е. «Ссылочный тип»). Для ссылочных типов .Equals сравнивает ссылочное равенство, а два экземпляра user1 и user2 - это две отдельные ссылки.

+0

Смотрите эту статью [MSDN] (https://msdn.microsoft.com/en-us/library/bsc2ak47 (v = vs.110) .aspx) о методе 'Object.Equals'. При сравнении типов значений 'int',' bool', 'long' и т. Д.' Object.Equals' будет выполняться так, как вы ожидаете. – BenM

+0

@BenM - Спасибо, но это не имеет значения. OP сравнивает типы ссылок, а не типы значений. –

2

По умолчанию reference types будет сравнивать ссылки. Это означает, что ваши 2 отдельных экземпляра, даже если их поля имеют одинаковое значение, являются разными объектами и будут сравниваться как неравенство. Вы можете изменить это поведение, предложив вашему классу реализовать IEquatable<T>, чтобы «научить» его сравнивать любым способом.

Отличный пример, который почти соответствует вашему использованию, находится на MSDN.

-1

Ваш класс Пользователь не реализует ничего, чтобы сообщить время выполнения, когда два объекта равны. Самый простой способ acchieve это путем перезаписи двух методов Equals и GetHashCode, как это:

public override bool Equals(object obj) 
{  
    User other = obj as User; 
    if(other == null) return false; 
    return other.Name == Name && other.IdNumber == IdNumber && other.OrgName == OrgName && other.AcctCode == AcctCode; 
} 

public override int GetHashCode() 
{ 
    return IdNumber.GetHashCode(); 
} 
0

Проблема эта линия:

user1.Equals(user2) 

Эта линия спрашивает, если объект user1 такой же, как user2. Они имеют одинаковые значения, но они не являются одним и тем же объектом в памяти.Если вы хотите сравнить значения этих двух объектов вы можете переопределить метод Equals так:

public static override Equals(User user2) 
{ 
    return (this.Name == user2.Name && 
      this.IdNumber == user2.IdNumber && 
      this.AcctCode == user2.AcctCode && 
      this.OrgName == user2.OrgName) 
} 
+2

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

+1

убедитесь, что вы сделали это правильно: «Рекомендуется, чтобы любой класс, который переопределяет Equals, также переопределяет System.Object.GetHashCode». [Рекомендации по перегрузке равных()] (https://msdn.microsoft.com/en-US/library/ms173147 (v = vs.80) .aspx) –