2009-04-08 14 views
3

エンティティと集約ルートを比較するときは、Oren Eini:Generic Entity Equalityから借りたABCを使用します。バリューオブジェクトの場合、私は同じように独創的でした。私はジミーボガードのバリューオブジェクトABCを使用しました:Generic Value Object Equalityコンポジション対等価およびハッシュコードプロバイダの継承

私の質問は次のとおりです。私はこれらのABCを継承したいと思っていますか?おそらく、汎用のequality/comparerを使用していて、代わりに前述の動作を構成していなければなりませんか?私は、上記の等価実装を再利用するつもりです。

これは、System.ObjectがデフォルトのEquals実装を持っていると思います。これは、言語の使い勝手を向上させますが、興味深い問題もあります。 Jon Skeetはここに詳しく説明しています:Comparison methods

誰も賛否両論はありますか?いろはを継承

  • が容易であると は ボックスの外にオペレータのオーバーロードを提供しています。
  • 2つの抽象度「ドラッグ」する必要がありますか? クラスは私と一緒にそんなに周りにいますか?それは 私の継承グラフをもっと複雑にする 複雑な/結合を追加します。
  • 私はDIを使って等価性 プロバイダを構成できましたか?

要約すると、エンティティのカスタム均等実装の使用経験はありますか?私の目的は、実装の選択肢をより深く理解し、プロジェクトのライフタイムを延ばし(エントロピーを減らし)、保守性を向上させるソリューションを実装することです。

答えて

0

これは本当にあなたの質問に答えるものではありませんが、私はあなたがここにある質問のいくつかを手助けしようとするプロジェクトだと思います。私はこの物を少し書いていましたが、それ以来それは何もしていません。

プロジェクトはEssence(http://essence.codeplex.com/)と呼ばれ、System.Linq.Expressionライブラリを使用して、Equals/GetHashCode/CompareTo/ToStringの標準表現を生成し(属性に基づいて)、IEqualityComparerを作成することができます。 IComparerクラスは引数リストに基づいています。 (私はいくつかのアイディアを持っていますが、あまりにも多くのことを続ける前にコミュニティーの意見を聞きたいのですが)。

これは、手書きとほぼ同じくらい速いことです。 CompareTo(); Linq.Expressionsが3.5リリースで変数の概念を持たないため、一致しないときに基礎オブジェクトのCompareTo()を2回呼び出す必要があります。 Linq.Expressionsにはこれを解決していますが、私はemit ilを使うことができたと思うが、当時インスパイアされていなかった。)

これはかなり簡単なアイデアだ。

ここでは、私はそれを研磨することに失望しています(これはコードプロジェクトの記事を書くこと、コードの一部を書いたことなどを含みます)。しかし、気分があればそうするように説得されるかもしれませんそれは興味深いものです。

(ダウンロード可能なパッケージはありません。ソースに行き、興味のあるものとして、#で書かれています(すべてのテストコードは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]); 
    } 

楽しくお楽しみください!

ポール。

+1

答えません。それにもかかわらず、面白い読書。ありがとう。 –

関連する問題