2013-05-15 4 views
1

У меня есть класс, который я сделал осуществить IEquatable<T> так, что, когда я тестирую я могу легко сравнить IEnumerable коллекции этих объектов с помощью вызова, таких как:тестирование Коллекция объектов по вопросам равенства с помощью IEquatable <T>

Assert.IsTrue(expected.SequenceEqual(actual)); 

В настоящее время это работает хорошо, но у меня есть несколько сомнительных сомнений. Класс выглядит следующим образом:

public class ThirdPartyClaim : IEquatable<ThirdPartyClaim> 
{ 
    // fields removed for question 

    public bool Equals(ThirdPartyClaim compareTo) 
    { 
     if (object.ReferenceEquals(this, compareTo)) 
     { 
      return true; 
     } 

     return this.ClaimId.Equals(compareTo.ClaimId) && 
       this.Firstname.Equals(compareTo.Firstname) && 
       this.Lastname.Equals(compareTo.Lastname); 
    } 

    public override int GetHashCode() 
    {  
     int hashClaimId = this.ClaimId == null ? 0 : this.ClaimId.GetHashCode(); 
     int hashFirstname = this.Firstname == null ? 0 : this.Firstname.GetHashCode(); 
     int hashLastname = this.Lastname == null ? 0 : this.Lastname.GetHashCode(); 

     return hashClaimId^hashFirstname^hashLastname; 
    } 

Мое понимание перекрывая GetHashCode() является то, что она используется для сравнения объектов, указывающих на тот же экземпляр класса. Очень маловероятно, что это потребуется по этому поводу (даже в будущем).

Правильно ли это понимание, и если да, могу ли я безопасно удалить код?

Есть ли лучший способ сравнить коллекции этих объектов в моем модульном тесте?

Хотя я ограничен, чтобы использовать MSTest.

Thans

+1

Нет, 'GetHashCode()' используется для вычисления хэш-кода для любого экземпляра. Любые поля, используемые в реализации 'Equals', также должны использоваться при вычислении хэш-кода. –

ответ

4

Переопределение GetHashCode требуется при перекрытии Equals, в противном случае на основе хэш-контейнеры могут работать неправильно. Из документации Object.Equals:

Типы, которые переопределяют Equals, также должны переопределять GetHashCode; в противном случае Hashtable может работать неправильно.

Даже если этот код не может быть применен в вашем случае, вы все равно должны его хранить. Помимо того, что правильно, это поможет вам проверить равенство коллекций независимо от их последовательности:

Assert.IsTrue(expected.Except(actual).Count() == 0);  

Одно изменение я бы к GetHashCode реализации ликвидирует свою симметрию: в настоящее время, переключение вокруг первого и последнего имени внутри вашего объекта приведет к созданию того же хэш-кода. Это неоптимально. Вы можете комбинировать несколько значений int xshh, умножая их на небольшое простое число, например. 31 и их добавление:

public override int GetHashCode() 
{  
    int hashClaimId = this.ClaimId == null ? 0 : this.ClaimId.GetHashCode(); 
    int hashFirstname = this.Firstname == null ? 0 : this.Firstname.GetHashCode(); 
    int hashLastname = this.Lastname == null ? 0 : this.Lastname.GetHashCode(); 

    return 31*31*hashClaimId + 31*hashFirstname^hashLastname; 
} 

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

  • Нет связанных вопросов^_^