.Equals方法由多个类使用

时间:2017-05-25 16:18:31

标签: c#

说我有这样的代码:

namespace Model
{
    public class Person
    {
        public int PersonID { get; set; }
        public string Name { get; set; }
    }
}

namespace Domain
{
    public class Person
    {
        public int PersonID { get; set; }
        public string Name { get; set; }
    }
}

namespace Presenter
{
    public class Person
    {
        public int PersonID { get; set; }
        public string Name { get; set; }
    }
}

说我想在我的测试中使用.equals。我是否必须为每个班级创建.equals,或者有没有办法分享.Equals()方法?

我创建了一个他们可以继承的超类。但是,Presenter命名空间中的对象已经从类继承。

2 个答案:

答案 0 :(得分:1)

如果它仅用于测试,则只生成一个帮助程序类,该对象将对象与对象进行比较,并尝试向内部强制转换为三个人(每个人)中的任何一个。

如果任何对象无法转换为3个类中的任何一个,则返回false。

答案 1 :(得分:0)

注意:就本Q& A而言,我忽略了更广泛的问题。也就是说,您似乎通过代码的不同层复制类型,这并不常见,但是您需要在每个层中实现相等性似乎很奇怪。通常情况下,对象彼此联系在一起,所需的平等逻辑将在" business"事物的终结,平等的结果基于该层的结果在整个过程中传播。我会认为这里确实需要您的请求,但至少要考虑您在其中一个层中确实只需要相等的可能性。

那说......

实现目标的最直接途径是"mixin"。无论好坏,这都不是C#语言所包含的功能。

从您的问题中不清楚这里的背景是什么或您想如何使用Equals()方法。 .NET Framework具有许多不同类型的相等场景,以及解决它们的不同方法。但是,如果您想要的是在每种类型中覆盖Equals()方法,那么您必须实际执行此操作。 C#没有提供任何机制来跨多个类提供单个覆盖实现。每个班级都需要修改。

请注意,您可以在某处创建一个实现相等的静态方法。您可以利用dynamic关键字来允许该方法与具有必要属性的任何类一起使用。例如:

namespace Model
{
    public class Person
    {
        public int PersonID { get; set; }
        public string Name { get; set; }

        public override bool Equals(object o)
        {
            return this.PersonEquals(o);
        }
    }
}

static class Extensions
{
    public static bool PersonEquals(this object person1, object person2)
    {
        if (person1.GetType() != person2.GetType())
        {
            return false;
        }

        dynamic d1 = person1, d2 = person2;

        return d1.PersonID == d2.PersonID && d1.Name == d2.Name;
    }
}

然后至少实际的实现只存在于一个地方。每个班级都只是代表那个。

虽然我不推荐它,但如果你想要两个不同类型的对象进行比较,你甚至可以删除类型比较。

请注意,根据惯例和良好做法,您还应覆盖GetHashCode()时覆盖Equals()。您可以使用与上述相同的方法来执行此操作。

如果您不需要对象本身来覆盖Equals(),那么您唯一关心平等的地方是在您始终能够提供IEqualityComparer<T>实现的环境中,那么您可以使用类似的方法,但无需修改原始类。例如:

class PersonEqualityComparer<T> : IEqualityComparer<T>
{
    public bool Equals(T x, T y)
    {
        dynamic d1 = x, d2 = y;

        return d1.PersonID == d2.PersonID && d1.Name == d2.Name;
    }

    public int GetHashCode(T obj)
    {
        dynamic d = obj;

        // ...or whatever your favorite hash code aggregation technique is here
        return d.PersonID.GetHashCode() * 37 + d.Name.GetHashCode();
    }
}