如何使用其基类进行良好的平等比较?

时间:2012-07-18 16:30:03

标签: c# list abstract-class equals abstraction

当我使用List.Contains(T item)时,我正在尝试进行比较。

问题是我使用BaseItem作为列表项。我需要验证列表中的一个对象是否具有与我计划添加的对象相同的属性值。

例如:

public abstract class BaseItem
{
    // some properties

    public override bool Equals(object obj)
    {
        return obj != null && this.GetType() == obj.GetType();
    }
}

public class ItemA : BaseItem
{
    public int PropertyA { get; set; }

    public override bool Equals(object obj)
    {
        if (base.Equals(obj) == false)
            return false;

        return (this.PropertyA == (obj as ItemA).PropertyA;
    }
}

public class ItemB : BaseItem
{
    public int PropertyB { get; set; }

    public override bool Equals(object obj)
    {
        if (base.Equals(obj) == false)
            return false;

        return this.PropertyB == (obj as ItemB).PropertyB;
    }
}

public class Program
{
    static void Main(string[] args)
    {
        List<BaseItem> items = new List<BaseItem>()
        {
            new ItemB() { PropertyB = 3 },
            new ItemA() { PropertyA = 2 },
            new ItemB() { PropertyB = 2 }
        };

        BaseItem newItem = new ItemA() { PropertyA = 2 };
        items.Contains(newItem);  // should return 'True', because the first element is equals than 'newItem'
    }
}

我不确定覆盖Equals方法是否正确,或者我是否必须实现IEquality接口。

1 个答案:

答案 0 :(得分:3)

测试集合成员资格的标准方法(列表成员资格,哈希集成员资格......)是使用.Contains方法,后者又使用IEquatable<T>.EqualsIEquatable<T>.Equals的默认实现(如果您不提供自己的实现)使用Object.Equals(Object))。

您当然可以实施IEquatable<T>。这将略微提高Contains检查的性能。请参阅msdn.microsoft.com/en-us/library/ms131190.aspx。

如果您实施IEquatable<T>,您仍应覆盖Object.EqualsObject.GetHashCode以提供一致的行为

  

如果实现了Equals,则还应该覆盖Object.Equals(Object)和GetHashCode的基类实现,以使它们的行为与IEquatable.Equals方法的行为一致。

http://msdn.microsoft.com/en-us/library/ms131190.aspx

有关相关讨论,请参阅此问题

Simplify Overriding Equals(), GetHashCode() in C# for Better Maintainability