在基类中实现IEquatable

时间:2014-03-23 20:38:00

标签: c# iequatable

我首先使用ASP.NET MVC和EntityFramework代码。

我正在尝试为将保存到我的数据库的所有对象创建一个基类(这里称为Entity类)。

有没有一种在基类中实现IEquatable的好方法?在我的实现中,我检查类型和ID - 这是一个很好的方法吗?这总是会返回最终派生类型吗?中间父母呢?

物件

public abstract class Entity : IEquatable<Entity>
{
    public int ID { get; set; }
    public string Name { get; set; }

    public Entity(string Name)
    {
        this.Name = Name;
    }

    public override string ToString() { return Name; }
    public override int GetHashCode() { return ID.GetHashCode(); }
    public override bool Equals(object obj) { return this == (Entity)obj; }
    public bool Equals(Entity other) { return this == other; }
    public static bool operator ==(Entity x, Entity y) { return Object.ReferenceEquals(x, y) ? true : ((object)x == null || (object)y == null) ? false : (x.GetType() == y.GetType() && x.ID.Equals(y.ID)); }
    public static bool operator !=(Entity x, Entity y) { return !(x == y); }
}

public abstract class Content : Entity
{
    public Content(string Name) : base(Name)
    {

    }
}

public class Page : Content
{
            public string Body { get; set; }
    public Page(string Name) : base(Name)
    {

    }
}

public class User : Entity
{
    public User(string Name) : base(Name)
    {

    }
}

数据库

每个派生对象类型通常都存在于单独的数据库中。但是,会有一些具有中间继承父级的对象共享主键。

假设有三个表包含以下列:     实体

  • 内容
    • ID
    • 名称
    • ID
  • 用户
    • ID
    • 名称

因此,Page和Content表共享一个主键。

2 个答案:

答案 0 :(得分:1)

  1. 没有必要实现IEquitable,它没有给出任何值(性能值,可读性值)。
  2. 在您的比较中,您仅依赖于引用相等性检查。您也应该检查ID相等。
  3. 您的GetHashCode()实现是次优的,您也应该包含实体的类型。
  4. 您确定所有实体都具有Name属性吗?在基类中,您应该包含在有界上下文的每个实体中显示的属性。
  5. 我在这里详细描述了这个主题:Domain object base class

答案 1 :(得分:0)

您的实施是正确的。

小心这样做。如果您可以拥有部分加载的对象,那么它们将被视为相等但可能没有所有相同的值。

如果您希望有时使用默认等号并且有时使用基于ID的等号,请创建一个实现IEqualityComparer<Entity>的单独助手类。