2009-06-17 14 views
9

一般的なインターフェイスまたはクラスを作成し、このクラスまたはインターフェイスの異なるバージョンを非汎用的な方法で使用したい場合があります。たとえば、私は次のようなインターフェースを持っています:ジェネリッククラスとインターフェイスの非汎用バージョン

interface ICanCreate<T> 
{ 
    T NewObject(); 
} 

これは、クラスをそのタイプのファクトリにすることができます。私は、一般的なファクトリクラスでこれらを登録したいので、私はこのような何か書いてみる:私は私の価値のために使うのですか種類の辞書で

public class Factory 
{ 
    private Dictionary<Type, ICanCreate> mappings; // what do I put here???? 

    public void RegisterCreator<T>(ICanCreate<T> creator) 
    {    
    } 

    public T Create<T>() 
    {    
    } 
} 

を?私は何らかの設計原則が欠落しているかどうかは分かりませんが、これはco(ntra?)の分散とはかなり関係があることを認識しています。どんな助けやアイデアも高く評価されます。

答えて

11

あなたはどちらかだけかICanCreate<T>非ジェネリックICanCreateインターフェースを宣言(それはプライベート、およびあなたがそこにあるものの間違った種類を置くことは決してないだろうことを確認することができますすべてです)あなたの辞書宣言でobjectを使用する必要があります拡張する。

基本的には、C#で表現できないタイプの関係が必要です。そのときには少し不愉快な解決策になりますが、ここでは醜さを分けることができますクラス)。

+0

?私がこのような状況にある場合、それはより洗練された解決策であると信じて、私は常にソリューションナンバー2に行きます。それですか、それとも重要ではありませんか? – Razzie

+2

あなたは非ジェネリックインターフェイスに感覚的に入れられるメンバーがいますか?インターフェイスが*ちょうど* Createメソッドであれば、オブジェクトに固執します。非ジェネリックインターフェイスは実際にあなたに何も与えません。他のケースでは、適切なタイプの引数が分からない非ジェネリックインターフェイスを参照するだけで逃げることができます。この場合、明らかな利点が得られます。 –

+0

クリア、コメントありがとう! – Razzie

3

興味深いことに、これは、C#4.0で解決されるという問題である:あなたが2の最も好ましいものは何だと思います

public interface ICanCreate<out T> // covariant 
{ 
    T NewObject(); 
} 

public class Factory 
{ 
    private Dictionary<Type, ICanCreate<object>> mappings = new Dictionary<Type, ICanCreate<object>>(); 

    public void RegisterCreator<T>(ICanCreate<T> creator) where T:class 
    {    
     mappings[typeof(T)] = creator; 
    } 

    public T Create<T>() 
    {    
     ICanCreate<object> creator = mappings[typeof(T)]; 
     return (T) creator.NewObject(); // I do not think you can get rid of this cast 
    } 
} 
+0

「out T」は何をしますか? – Svish

+0

@Svish:それはTを共変量としてマークします。 –

+0

ええ、それはどういう意味ですか?あなたはそれに関する情報を持ったリンクを持っていますか? – Svish

関連する問題