类型对象的多个属性的动态相等检查

发布于 2024-10-17 12:36:16 字数 849 浏览 6 评论 0原文

我有这样的类型:

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 接口来检查该类型的两个对象是否相同。当前的 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));
}

但我希望以这样的方式实现此方法:动态检查所有现有属性(或者可能是此类型的某些属性)的相等性,而无需显式编写代码进行上述比较检查。

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

谢谢!

I have a type like:

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

I've implemented the IEquatable<T> interface to check if two objects of this type are same or not. The current Equals method looks like:

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

But I wish to implement this method in such a way that it dynamically checks for equality of all the existing properties (or maybe certain properties of this type) without explicitly writing the code for comparison checks as above.

Hope I was able to express my question with clarity. :)

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

小巷里的女流氓 2024-10-24 12:36:17

您可以编写一个自定义属性,该属性附加到您想要包含在比较中的类型的属性。然后,在 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;
    }
}

它肯定需要比这更复杂一些,但这应该会让您走上正确的轨道:)

You could write a custom attribute that attaches to the properties on your type which you want to be included in the comparision. Then in the Equals method you could reflect over the type and extract all the properties which have the attribute, and run a comparison on them dynamically.

Psuedo code:

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

It'll certianly need to be a bit more elaborate than that, but that should hopefully set you on the right track :)

北音执念 2024-10-24 12:36:17

如果两个 Order 的所有属性都相等,则它们被视为相同。 Name/TotalPurchases/Amount/Code 4 个属性没问题,它们的默认比较器正是您想要的。但对于属性 AllItems(其类型为 List),您必须告诉它们如何被视为相等。目前您使用的引用等于是不正确的。 this.AllItems.Equals(other.AllItems) 应该类似于:

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

ItemComparer 是一个实现 IEqualityComparer 的类来告诉如何检查两个 Item 是否相等。

Two Orders are considered the same if all their properties are equal. It's OK for the 4 properties Name/TotalPurchases/Amount/Code, their default comparers are exactly what you want. But for the property AllItems (whose type is List<IItem>), you must tell how they consider to be equal. Currently you are using reference equals that is incorrect. this.AllItems.Equals(other.AllItems) should be something like:

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

And the ItemComparer is a class implements IEqualityComparer<Item> to tell how to check if two Items are equal.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文