Динамическая проверка на равенство нескольких свойств объектов типа - PullRequest
1 голос
/ 16 февраля 2011

У меня есть такой тип:

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 ]

2 голосов
/ 16 февраля 2011

Вы можете написать собственный атрибут, который присоединяется к свойствам вашего типа, которые вы хотите включить в сравнение. Затем в методе Equals вы можете отразить тип и извлечь все свойства, которые имеют атрибут, и динамически выполнить сравнение с ними.

Код Psuedo:

[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;
    }
}

Конечно, это должно быть немного сложнее, но это, мы надеемся, поставит вас на правильный путь:)

1 голос
/ 16 февраля 2011

Два Order считаются одинаковыми, если все их свойства равны. Это нормально для 4 свойств Name / TotalPurchases / Amount / Code, их компараторы по умолчанию - именно то, что вам нужно. Но для свойства AllItems (тип которого List<IItem>) вы должны указать , как они считают равными. В настоящее время вы используете ссылку равно, что неверно. this.AllItems.Equals(other.AllItems) должно быть что-то вроде:

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

И ItemComparer - это класс, реализующий IEqualityComparer<Item>, чтобы сказать, как проверить, равны ли два Item.

...