Inheritance 平等与平等的组合与继承;哈希代码提供程序

Inheritance 平等与平等的组合与继承;哈希代码提供程序,inheritance,oop,equality,composition,Inheritance,Oop,Equality,Composition,当比较实体和聚合根时,我使用ABC,这是我从Oren Eini借用的:。对于有价值的东西,我也同样聪明。我使用了Jimmy Bogard的价值对象ABC: 现在我的问题是,;我应该倾向于继承这些ABC,还是应该使用泛型/组合上述行为?我打算重用上述平等实现 我认为这又回到了System.Object,它有一个默认的等于实现,这使得语言非常容易使用,但也带来了有趣的难题。Jon Skeet在此详细介绍: 有人能想出什么赞成或反对的意见吗 继承ABC更容易,也更容易 提供的运算符重载超出了 盒子

当比较实体和聚合根时,我使用ABC,这是我从Oren Eini借用的:。对于有价值的东西,我也同样聪明。我使用了Jimmy Bogard的价值对象ABC:

现在我的问题是,;我应该倾向于继承这些ABC,还是应该使用泛型/组合上述行为?我打算重用上述平等实现

我认为这又回到了System.Object,它有一个默认的等于实现,这使得语言非常容易使用,但也带来了有趣的难题。Jon Skeet在此详细介绍:

有人能想出什么赞成或反对的意见吗

  • 继承ABC更容易,也更容易 提供的运算符重载超出了 盒子
  • 我应该“拖拽”两个抽象概念吗 你经常和我一起上课吗?信息技术 使我的继承图更加 复杂/增加耦合
  • 我可以使用DI来编写等式 提供者

总之,有没有人有过为实体使用自定义平等实现的经验?我的目标是更全面地了解实施选择,并实施一个解决方案,这将延长项目的生命周期(减少熵)并提高可维护性。

这并不能真正回答您的问题(对不起!),但我认为这是一个试图帮助您解决一些问题的项目。我不久前写过这篇文章,但从那时起就没有做过任何事情

该项目称为Essence(),它使用System.Linq.Expression库(基于属性)生成Equals/GetHashCode/CompareTo/ToString的标准表示形式,并能够基于参数列表创建IEqualityComparer和IComparer类。(我也有一些进一步的想法,但在继续深入之前,我希望获得一些社区反馈。)

(这意味着它几乎和手写一样快——最主要的不是CompareTo();因为Linq.Expressions在3.5版本中没有变量的概念——所以必须调用CompareTo())在没有匹配的情况下,在底层对象上执行两次。使用Linq.Expressions的DLR扩展可以解决此问题。我想我本可以使用emit il,但当时我并没有那么受启发。)

这是一个相当简单的想法,但我以前从未见过这样做

现在的问题是,我对润色它有点失去了兴趣(包括为codeproject写一篇文章,记录一些代码等等),但是如果你觉得有兴趣的话,我可能会被说服这样做

(codeplex站点没有可下载的软件包;只需转到源代码并获取它-哦,它是用f#编写的(尽管所有测试代码都是用c#编写的),因为这是我感兴趣的学习内容。)

无论如何,这里有一些来自我的测试用例的c#示例

    // --------------------------------------------------------------------
    // USING MY ESSENCE LIBRARY:
    // --------------------------------------------------------------------
    [EssenceClass(UseIn = EssenceFunctions.All)]
    public class TestEssence : IEquatable<TestEssence>, IComparable<TestEssence>
    {
        [Essence(Order=0, Format="i={0},")]           public int MyInt           { get; set; }
        [Essence(Order=1, Format="s={0},")]           public string MyString     { get; set; }
        [Essence(Order=2, Format="d={0:yyyy-MM-dd}")] public DateTime MyDateTime { get; set; }

        public override int GetHashCode()                                { return Essence<TestEssence>.GetHashCodeStatic(this); }
        public override string ToString()                                { return Essence<TestEssence>.ToStringStatic(this); }
        public int CompareTo(TestEssence other)                          { return Essence<TestEssence>.CompareToStatic(this, other); }

        public static bool operator ==(TestEssence lhs, TestEssence rhs) { return Essence<TestEssence>.EqualsStatic(lhs, rhs); }
        public override bool Equals(object obj)                          { return this == (TestEssence)obj; }
        public bool Equals(TestEssence other)                            { return this == other; }
        public static bool operator !=(TestEssence lhs, TestEssence rhs) { return !(lhs == rhs); }
    }

    // --------------------------------------------------------------------
    // EQUIVALENT HAND WRITTEN CODE:
    // --------------------------------------------------------------------
    public class TestManual
    {
        public int MyInt;
        public string MyString;
        public DateTime MyDateTime;

        public override int GetHashCode()
        {
            var x = MyInt.GetHashCode();
            x *= Essence<TestEssence>.HashCodeMultiplier;
            x ^= (MyString == null) ? 0 : MyString.GetHashCode();
            x *= Essence<TestEssence>.HashCodeMultiplier;
            x ^= MyDateTime.GetHashCode();
            return x;
        }

        public static bool operator ==(TestManual lhs, TestManual rhs)
        {
            if (ReferenceEquals(lhs, null))
            {
                if (ReferenceEquals(rhs, null))
                    return true;
                return false;
            }
            if (ReferenceEquals(rhs, null))
                return false;
            if (ReferenceEquals(lhs, rhs))
                return true;
            if (typeof(TestManual) != rhs.GetType())
                return false;

            return lhs.MyInt == rhs.MyInt
                && lhs.MyString == rhs.MyString
                && lhs.MyDateTime == rhs.MyDateTime;
        }

        public override bool Equals(object obj)                 { return this == obj as TestManual; }
        public bool Equals(TestManual other)                    { return this == other; }
        public static bool operator !=(TestManual lhs, TestManual rhs) { return !(lhs == rhs); }

        public override string ToString()
        {
            if (MyString == null)
                return string.Format("i={0},d={1:yyyy-MM-dd}", MyInt, MyDateTime);

            return string.Format("i={0},s={1},d={2:yyyy-MM-dd}", MyInt, MyString, MyDateTime);
        }

        public int CompareTo(TestManual other)
        {
            if (other == null)
                return 1;
            if (ReferenceEquals(this, other))
                return 0;

            int result = 0;

            result = MyInt.CompareTo(other.MyInt);
            if (result != 0) return result;
            result = MyString.CompareTo(other.MyString);
            if (result != 0) return result;
            result = MyDateTime.CompareTo(other.MyDateTime);
            if (result != 0) return result;

            return result;
        }
    }

    // --------------------------------------------------------------------
    // --------------------------------------------------------------------
    // ALTERNATIVE USAGE
    // --------------------------------------------------------------------
    // --------------------------------------------------------------------

    class Simple
    {
        public Simple(int value) { Value1 = value; }
        public Simple(int value1, int value2) { Value1 = value1; Value2 = value2; }
        public readonly int Value1;
        public readonly int Value2;
    }

    [Test]
    public void TestReverseForwardString()
    {
        var _11 = new Simple(1, 1);
        var _12 = new Simple(1, 2);
        var _21 = new Simple(2, 1);
        var _22 = new Simple(2, 2);

        var items = new[] { _11, _12, _21, _22 };
        var reverseComparer = Essence<Simple>.CreateComparer("-Value1", "Value2");

        Array.Sort(items, reverseComparer);

        Assert.AreSame(_21, items[0]);
        Assert.AreSame(_22, items[1]);
        Assert.AreSame(_11, items[2]);
        Assert.AreSame(_12, items[3]);
    }

    [Test]
    public void TestReverseForwardLambda()
    {
        var _11 = new Simple(1, 1);
        var _12 = new Simple(1, 2);
        var _21 = new Simple(2, 1);
        var _22 = new Simple(2, 2);

        var items = new[] { _11, _12, _21, _22 };
        var reverseComparer = Essence<Simple>.CreateComparer(x => x.Action.ReverseNext, x => x.Member.Value1, x => x.Member.Value2);

        Array.Sort(items, reverseComparer);

        Assert.AreSame(_21, items[0]);
        Assert.AreSame(_22, items[1]);
        Assert.AreSame(_11, items[2]);
        Assert.AreSame(_12, items[3]);
    }
//--------------------------------------------------------------------
//使用我的精华库:
// --------------------------------------------------------------------
[EssenceClass(UseIn=EssenceFunctions.All)]
公共类测试:IEquatable,IComparable
{
[Essential(Order=0,Format=“i={0},”)]public int MyInt{get;set;}
[Essential(Order=1,Format=“s={0},”)]public string MyString{get;set;}
[Essence(Order=2,Format=“d={0:yyyy-MM-dd}”)]公共日期时间MyDateTime{get;set;}
public override int GetHashCode(){return Essential.GetHashCodeStatic(this);}
公共重写字符串ToString(){return Essential.ToString静态(this);}
public int CompareTo(TestEssence-other){返回精华。CompareToStatic(this,other);}
公共静态布尔运算符==(TesteSence lhs,TesteSence rhs){返回Essential.equalStatic(lhs,rhs);}
public override bool Equals(object obj){返回this==(TestEssence)obj;}
public bool Equals(TestEssence other){返回this==other;}
公共静态布尔运算符!=(TestEssence lhs,TestEssence rhs){return!(lhs==rhs);}
}
// --------------------------------------------------------------------
//等效手写代码:
// --------------------------------------------------------------------
公共类测试手册
{
公共int-MyInt;
公共字符串MyString;
公共日期时间MyDateTime;
公共覆盖int GetHashCode()
{
var x=MyInt.GetHashCode();
x*=Essential.HashCode乘数;
x^=(MyString==null)?0:MyString.GetHashCode();
x*=Essential.HashCode乘数;
x^=MyDateTime.GetHashCode();
返回x;
}
公共静态布尔运算符==(TestManual lhs、TestManual rhs)
{
if(ReferenceEquals(lhs,null))
{
if(ReferenceEquals(rhs,null))
返回true;
返回false;
}
if(ReferenceEquals(rhs,null))
返回false;
if(参考等于(左、右))
返回true;
if(typeof(TestManual)!=rhs.GetType()
返回false;
返回lhs.MyInt==rhs.MyInt
&&lhs.MyString==rhs.MyString
&&lhs.MyDateTime==rhs.MyDateTime;
}
public override bool Equals(object obj){将this==obj作为TestManual返回;}
public bool Equals(TestManual other){返回this==other;}
公共静态布尔运算符!=(TestManual lhs,TestManual rhs){返回!(lhs==rhs);}
公共重写字符串ToStr