2011-02-16 71 views
1

我有一个类似类型的多个属性的检查:动态平等类型的对象

class Order 
{ 
    public List<IItem> AllItems { get; set; } 
    public string Name { get; set; } 
    public double TotalPurchases { get; set; } 
    public long Amount { get; set; } 
    public int Code { get; set; } 
} 

我已经实现了IEquatable<T>接口检查,如果这种类型的两个对象是相同的或没有。目前Equals方法是这样的:

public virtual bool Equals(Order other) 
{ 
    if ((object)other == null) 
    { 
    return false; 
    } 
    return (this.AllItems.Equals(other.AllItems) 
     && this.Name.Equals(other.Name) 
     && this.TotalPurchases.Equals(other.TotalPurchases) 
     && this.Amount.Equals(other.Amount)) 
     && this.Code.Equals(other.Code)); 
} 

但我想以这样的方式来实现这个方法,它动态地检查所有的现有属性(或这种类型的,也许某些属性)的平等,而不明确地编写代码用于比较检查如上。

希望我能清楚地表达我的问题。 :)

谢谢!

回答

2

您可以编写一个自定义属性,该属性附加到您想要包含在比较中的类型的属性上。然后在Equals方法中,您可以反映该类型并提取具有该属性的所有属性,并动态地对它们进行比较。

的伪代码:

[AttributeUsage(AttributeTarget.Property)] 
class IncludeInComparisonAttribute : Attribute { } 

class Order 
{ 
    List<AllItem> Items { get; set; } 

    [IncludeInComparison] 
    string Name { get; set; } 

    long Amount { get; set; } 

    [IncludeInComparison] 
    int Code { get; set; } 

    override bool Equals(Order other) 
    { 
     Type orderType = typeof(Order); 

     foreach (PropertyInfo property in orderType.GetProperties() 
     { 
      if (property.CustomAttributes.Includes(typeof(IncludeInComparisonAttribute)) 
      { 
       object value1 = property.GetValue(this); 
       object value2 = propetty.GetValue(other); 

       if (value1.Equals(value2) == false) 
        return false; 
      } 
     } 

     return true; 
    } 
} 

它会certianly需要比这更复杂一点,但应该希望你设定在正确的轨道:)

+0

恩,谢谢。会试试这个。 – Dienekes 2011-02-16 09:54:17

1

两个Order s被认为在上如果它们的所有属性都相同,则相同这4个属性名称/总购买量/金额/代码是可以的,它们的默认比较器正是你想要的。但对于属性AllItems(其类型为List<IItem>),您必须告诉他们认为他们是如何平等的。目前您使用的引用等于不正确。 this.AllItems.Equals(other.AllItems)应该是这样的:

this.AllItems.SequenceEqual(other.AllItems, new ItemComparer()) 

而且ItemComparer是一个类实现IEqualityComparer<Item>告诉如何检查两个Item s为相等。

+0

我会说你甚至不想在比较中包含AllItems属性。唯一需要比较的属性是让订单唯一(名称代码?)的属性。理想情况下它应该有一个唯一的标识符。你的建议是好的,但假设他想要比较列表:) – MattDavey 2011-02-16 09:23:16