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>()
    {            
    }
}

辞書では、値にどのタイプを使用しますか?ある種の設計原理が欠けているかどうかはわかりませんが、これは共(ntra?)分散と多くの関係があることを認識しています。どんな助けやアイデアも大歓迎です。

4

2 に答える 2

11

辞書宣言で使用するかobject(すべてプライベートであり、間違った種類のものを入れないことを確認できます)、拡張する非汎用ICanCreateインターフェースを宣言する必要があります。ICanCreate<T>

基本的に、C#で表現できない型の関係が必要です。そうなると、少し不快な解決策になりますが、ここで醜いものを分離できるように見えます(つまり、単一のクラス内に保持できます)。

于 2009-06-17T08:59:22.887 に答える
3

興味深いことに、これは C# 4.0 で解決された問題です。

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
    }
}
于 2009-06-17T10:23:53.577 に答える