2012-12-08 68 views
2

我需要同步在线数据库和本地数据库的约会。 这是我到目前为止的代码:比较列表中对象的属性

 List<Appointment> onlineAppointments = new List<Appointment>(); 
     List<Appointment> localAppointments = new List<Appointment>(); 
     Appointment appointment01 = new Appointment(new DateTime(2012, 12, 24, 17, 30, 00), new DateTime(2012, 12, 24, 17, 45, 00), name, 123, "comment", 0, "test", 123, 1, DateTime.Now); 
     Appointment appointment02 = new Appointment(new DateTime(2012, 12, 24, 17, 30, 00), new DateTime(2012, 12, 24, 17, 45, 00), name, 123, "comment", 0, "test", 123, 1, DateTime.Now); 

     onlineAppointments.Add(appointment01); 
     localAppointments.Add(appointment02); 

因为我只是想比较我创立的IEqualityComparer对象的某些属性:

public class AppointmentEqualityComparer<T> : IEqualityComparer<T> where T : Appointment 
{ 
    #region IEqualityComparer<T> Members 

    public bool Equals(T x, T y) 
    { 
     return (x == null && y == null) || ((x != null && y != null) && 
     (x.getAppointmentStart() == y.getAppointmentStart() && 
     x.getAppointmentEnd() == y.getAppointmentEnd()) 
     ); 
    } 

    /// </exception> 
    public int GetHashCode(T obj) 
    { 
     if (obj == null) 
     { 
      throw new ArgumentNullException("obj"); 
     } 

     return obj.GetHashCode(); 
    } 

    #endregion 
} 

不幸的是,这并不工作:

var comparer = new AppointmentEqualityComparer<Appointment>();  
IEnumerable<Appointment> diffOnlineOffline = onlineAppointments.Except(localAppointments, comparer); 

含义diffOnlineOffline不是空的,但它应该是因为这两个列表包含相同的约会。

有什么想法?

+0

我没有看到在EqualityComparer任何问题。您是否已经完成了执行并检查了两个约会的价值? – rae1

+0

您的哈希码实现应该使用与您的相等比较相同的属性,即'AppointmentStart'和'AppointmentEnd'。 – Lee

+0

你是什么意思@Lee?对不起,但我不太明白你的意思......你能给我一个具体的例子吗? – libjup

回答

2

GetHashCode方法应该使用用于平等性。目前,你想要考虑的对象可能不会有相同的哈希码。

您可以使用这样的事情:

public int GetHashCode(T obj) 
{ 
    return 41 * (41 * (41 * (41 + obj.getAppointmentStart().GetHashCode())) 
    + obj.getAppointmentEnd().GetHashCode()); 
} 
1

我怀疑问题是与getAppointmentStartgetAppointmentEnd方法。下面是使用相同的相等比较你的代码的简洁版,但通过作为预期性:

public class Appointment 
{ 
    private int Id { get; set; } 
    public DateTime Start { get; set; } 
    public DateTime End { get; set; } 

    public Appointment(int id, DateTime start, DateTime end) 
    { 
     Start = start; 
     End = end; 
     Id = id; 
    } 
} 


public class AppointmentEqualityComparer<T> : IEqualityComparer<T> where T : Appointment 
{ 
    #region IEqualityComparer<T> Members 

    public bool Equals(T x, T y) 
    { 
     return (x == null && y == null) 
       || ((x != null && y != null) && (x.Start == y.Start && x.End == y.End)); 
    } 

    public int GetHashCode(T obj) 
    { 
     if(obj == null) 
     { 
      throw new ArgumentNullException("obj"); 
     } 

     return obj.GetHashCode(); 
    } 

    #endregion 
} 

和实现:

var onlineAppointments = new List<Appointment>(); 
var localAppointments = new List<Appointment>(); 
var appointment01 = new Appointment(1, new DateTime(2012, 12, 24, 17, 30, 00), 
             new DateTime(2012, 12, 24, 17, 45, 00)); 
var appointment02 = new Appointment(2, new DateTime(2012, 12, 24, 17, 30, 00), 
             new DateTime(2012, 12, 24, 17, 45, 00)); 

onlineAppointments.Add(appointment01); 
localAppointments.Add(appointment02); 

var comparer = new AppointmentEqualityComparer<Appointment>(); 
var diffOnlineOffline = onlineAppointments.Except(localAppointments, comparer).ToList(); 

diffOnlineOffline只显示了第一次约会。这导致getAppointmentStartgetAppointmentEnd方法正在返回除构造函数中使用的实际日期以外的值。

+0

感谢您的回答! 但它仍然无效:( foreach(预约diffOnlineOffline约会) { MessageBox。显示(“列表中至少有1个约会”); } 仍然执行... – libjup

+0

找出它的工作原理。只需要实施@李的解决方案以及...但无论如何谢谢! – libjup

+0

根据2个样本列表,您在'diffOnlineOffline'中预期会有多少个约会? –

0

你需要在你的约会类来实现的IEqualityComparer

+1

相同您可以将EqualityComparer传递给Except(这是OP中发生的事情),所以不需要在域类 –

+0

中实现IEqualityComaprer啊谢谢澄清! – Nikos