2009-07-24 10 views
4

自己参照汎用継承を使用することをお勧めしますか?Customer:Entityのような自己参照汎用継承を使用する必要があります<Customer>

public abstract class Entity<T> { 
    public Guid Id {get; set;} 
    public int Version {get; set;} 

    public T Clone() { 
     ... 
     // clone routine 
     ... 
     return T; 
    } 
} 

public class Customer : Entity<Customer> { 
    public string CustomerName {get; set;} 
    ... 
} 

お客様は、どのように基本エンティティクラスにキャストしますか? 「顧客:エンティティ」はどのような利点を提供しますか? NHibernateドメインモデリングを示す例では、このような継承があります。

ジェネリックスを使用せずに「顧客:エンティティ」を使用する方がよいですか?

答えて

4

可能な場合だけでなく、必要なときに使用する必要があります。上記の例では、Clone()を実装するのに意味があります。しかし、あなたが正しく指摘したように、エンティティクラスは実際には共通の基底クラスを持たず、それらに本当に共通のプロパティにアクセスできなくなります。これを処理するための正しい方法ジェネリックと非ジェネリックの部分でそれを分割することです:

public abstract class Entity { 
    public Guid Id {get; set;} 
    public int Version {get; set;} 
} 

public abstract class Entity<T> : Entity where T : Entity<T> { 
    public T Clone() { 
     ... 
     // clone routine 
     ... 
     return T; 
    } 
} 

また、私はEntity<T>の宣言に追加したwhere部分を注意してください - それは、このクラスでのみ使用することができることを保証しますこの再帰的パターンの一部として

+0

汎用エンティティを使用する利点はありますか?他の利点がない場合、私はクローンメソッドを汎用メソッドにすることができます。 – Mank

+0

どのように 'クローン'ジェネリックを作りますか? –

+0

私はpublicを行うことができましたT Clone (){Tのシリアル化/逆シリアル化} – Mank

3

私が働く会社では、私が取り組んでいるプロジェクトでは、この種のトリックを頻繁に使用しています。実際には、コード内のパターンとしても宣伝されています。したがって私は経験から話すことができます:それを使用しないでください。

自己参照の実装がはるかに簡単で、効率的で読みやすくなりますが、このような場合は発生しませんでした。コードメンテナンスを大量に使用すると、コードのメンテナンスが悪化し、必要に応じて通常の継承とメソッド結果のキャストのみで回避できます。また、派生クラスへのキャストのパフォーマンスコストは、コードのメンテナンスコストに比べて無視できます。

したがって、自己参照汎用継承を使用することをお勧めするまれな例が見つかった場合は、先に進んでください。おそらくそれを行うより良い方法があるので、事前に2度考えてください。

関連する問題