Ho scritto una classe di confronto personalizzata.Perché due nuovi oggetti non hanno lo stesso codice hash?
public class ItemComparer : IEqualityComparer<Item>
{
public int GetHashCode(Item x)
{
return (x == null) ? 0 : new { x.Name, x.CompanyCode,
x.ShipToDate, x.Address }.GetHashCode();
}
Ho un test che fallisce quando ho nuove fino due prodotti e confrontare i codici hash. Perché gli hash sono diversi?
[TestMethod]
public void Two_New_Items_Have_The_Same_Hash_Code()
{
// arrange
var comparer = new ItemComparer();
Item x = new Item();
Item y = new Item();
// act
int xHash = comparer.GetHashCode(x);
int yHash = comparer.GetHashCode(y);
// assert
Assert.AreEqual(xHash, yHash);
}
MODIFICA - Ecco la classe completa. Ho originariamente usato l'esempio di cui sopra per brevità, ma sono necessarie maggiori informazioni
public class DtoPolicy : DtoBase
{
[Description("The Policy Number")]
public string PolicyNumber { get; set; }
[Description("The Agent Code for the Agent who wrote the policy.")]
public string AgentCode { get; set; }
[Description("The First Name of the insured")]
public string FirstName { get; set; }
[Description("The Last Name of the insured")]
public string LastName { get; set; }
[Description("The Date of Birth of the insured")]
public DateTime DateOfBirth { get; set; }
[Description("The Age of the insured")]
public int Age { get; set; }
[Description("The Issue Date of the Policy")]
public DateTime PolicyIssueDate { get; set; }
[Description("The current status of the policy")]
public string PolicyStatus { get; set; }
public string TypeOfCoverage { get; set; }
public string PlanDescription { get; set; }
public decimal CompanyCode { get; set; }
public DateTime? TerminationDate { get; set; }
public decimal PolicyHolderSSN { get; set; }
[Description("The Zip Code of the insured")]
public string ZipCode { get; set; }
public decimal OwnerSSN { get; set; }
public string EmailAddress { get; set; }
public string WebUsername { get; set; }
public string OwnerFirstName { get; set; }
public string OwnerLastName { get; set; }
public string PayorFirstName { get; set; }
public string PayorLastName { get; set; }
public DateTime? PolicyEffectiveDate { get; set; }
public string AgentName { get; set; }
public string AgentPhone { get; set; }
public string InsuredCityState { get; set; }
public string InsuredAddress1 { get; set; }
public string InsuredAddress2 { get; set; }
public string InsuredCity { get; set; }
public string InsuredState { get; set; }
public string InsuredPhone { get; set; }
public string OwnerAddress1 { get; set; }
public string OwnerAddress2 { get; set; }
public string OwnerCity { get; set; }
public string OwnerState { get; set; }
public string OwnerZip { get; set; }
public string OwnerPhone { get; set; }
public string PayorAddress1 { get; set; }
public string PayorAddress2 { get; set; }
public string PayorCity { get; set; }
public string PayorState { get; set; }
public string PayorZip { get; set; }
public string PayorPhone { get; set; }
public DateTime? PaidToDate { get; set; }
public DateTime? LastPaidDate { get; set; }
public string PremiumMode { get; set; }
public decimal PremiumAmount { get; set; }
public DateTime? LastBillDate { get; set; }
public string BillingStatus { get; set; }
public decimal TotalLoanAmount { get; set; }
public decimal DividendAccumulation { get; set; }
public decimal ModalPremiumMonthly { get; set; }
public decimal ModalPremiumSemiAnnual { get; set; }
public decimal ModalPremiumQuarterly { get; set; }
public decimal ModalPremiumAnnual { get; set; }
public bool ElectronicBilling { get; set; }
public List<DtoClaim> Claims { get; set; }
public decimal MarketCode { get; set; }
public string BillingMode { get; set; }
public DtoPolicy()
{
Claims = new List<DtoClaim>();
}
}
Questa implementazione di GetHashCode restituisce anche diversi hash per due nuovi oggetti
public int GetHashCode(DtoPolicy x)
{
return (x == null) ? 0 : x.Age.GetHashCode()^x.AgentCode.GetHashCode()^x.AgentName.GetHashCode()^x.AgentPhone.GetHashCode()^
x.BillingMode.GetHashCode()^x.BillingStatus.GetHashCode()^
x.Claims.GetHashCode()^x.CompanyCode.GetHashCode()^x.DateOfBirth.GetHashCode()^x.DividendAccumulation.GetHashCode()^
x.ElectronicBilling.GetHashCode()^x.EmailAddress.GetHashCode()^x.FirstName.GetHashCode()^x.InsuredAddress1.GetHashCode()^
x.InsuredAddress2.GetHashCode()^x.InsuredCity.GetHashCode()^x.InsuredCityState.GetHashCode()^x.InsuredPhone.GetHashCode()^
x.InsuredState.GetHashCode()^x.LastBillDate.GetHashCode()^x.LastName.GetHashCode()^
x.LastPaidDate.GetHashCode()^x.MarketCode.GetHashCode()^x.ModalPremiumAnnual.GetHashCode()^x.ModalPremiumMonthly.GetHashCode()^
x.ModalPremiumQuarterly.GetHashCode()^x.ModalPremiumSemiAnnual.GetHashCode()^x.OwnerAddress1.GetHashCode()^
x.OwnerAddress2.GetHashCode()^x.OwnerCity.GetHashCode()^x.OwnerFirstName.GetHashCode()^
x.OwnerLastName.GetHashCode()^x.OwnerPhone.GetHashCode()^x.OwnerSSN.GetHashCode()^x.OwnerState.GetHashCode()^
x.OwnerZip.GetHashCode()^x.PaidToDate.GetHashCode()^x.PayorAddress1.GetHashCode()^
x.PayorAddress2.GetHashCode()^x.PayorCity.GetHashCode()^x.PayorFirstName.GetHashCode()^x.PayorLastName.GetHashCode()^
x.PayorPhone.GetHashCode()^x.PayorState.GetHashCode()^x.PayorZip.GetHashCode()^
x.PlanDescription.GetHashCode()^x.PolicyEffectiveDate.GetHashCode()^x.PolicyHolderSSN.GetHashCode()^
x.PolicyIssueDate.GetHashCode()^x.PolicyNumber.GetHashCode()^x.PolicyStatus.GetHashCode()^
x.PremiumAmount.GetHashCode()^x.PremiumMode.GetHashCode()^x.TerminationDate.GetHashCode()^
x.TotalLoanAmount.GetHashCode()^x.TypeOfCoverage.GetHashCode()^x.WebUsername.GetHashCode()^x.ZipCode.GetHashCode();
}
È questo il tuo codice attuale? Non stai usando il comparatore da nessuna parte, e questo verrà compilato solo se c'è una conversione implicita da 'Item' a' int'. – Lee
Questo non sembra giusto: 'int xHash = new Item();'. Penso che tu intenda 'int xHash = comparer.GetHashCode (x);'. – Guffa
Scusa, ho corretto la parte 'act', l'ho scritta male. –