2011-07-10 18 views
1

で作業していない:共分散は、以下のクラスを考えると、一般的な辞書エントリ

public class ConcreteEmployeeRoleCreator<T, TConcrete, TSpec> 
    where TConcrete : class, T, new() 
    where T : EmployeeRole 
    where TSpec : EmployeeRoleSpecification 
{ 
    public ConcreteEmployeeRoleCreator(TSpec spec) { Specification = spec; } 

    public TSpec Specification { get; private set; } 

    public T Create() { return new TConcrete(); } 

} 

私は「クリエイター」の辞書を持っていると思いますが、私はまだそれを行う方法を考え出すことができませんでした。私が試してみて、最小公分母のタイプを使用して辞書を定義する場合、コンパイラは、「インスタンスがセールスマン

[Test] public void Creator_CanCreateFromSpec() { var creators = new Dictionary<string, ConcreteEmployeeRoleCreator<EmployeeRole, EmployeeRole, EmployeeRoleSpecification>>(); var spec = new SalesmanRoleSpecification(); var creator = new ConcreteEmployeeRoleCreator<EmployeeRole, Salesman, SalesmanRoleSpecification>(spec); creators.Add("salesman", creator); <==== ** compile error ** } 

がEmployeeRoleで、SalesmanRoleSpecification がEmployeeRoleSpecificationである(または私はwouldn

を追加することができるようにされていませんコンパイラエラーもなく上記の作成者を定義することができます)。

だから私は辞書を宣言していると思いますか?私は間違って何をしていますか?

+0

しかし、どのコンパイラ実際には? – Tigran

+1

分散は、インターフェイス、具体的な実装ではありません(ただしこれに限定されません)。 –

+0

C#4.0またはC#4.0で改善しましたか? –

答えて

3

汎用共分散を有する

乾杯、
Berrylは、共変タイプの宣言時に指定される - それはのみは、インターフェイスとデリゲートに指定することができます。

だから、あなたはクラスを使用していることを考えると、

ConcreteEmployeeRoleCreator<EmployeeRole, Salesman, SalesmanRoleSpecification> 

は、あなたは別のアプローチを探すために必要があります

ConcreteEmployeeRoleCreator<EmployeeRole, EmployeeRole, EmployeeRoleSpecification> 

になることはありません。正直言って、3つのタイプのパラメータを取得し、それらのうちの2つを共変することを望むときには、まずはわかりにくい設計をしています。(

+0

私は実際にあなたのほうに安心しています! '97年のReumer氏の「Role Object Pattern」のデザインを通して、別のパターンを使用している「Product Trader」*私が思い付いたジェネリッククラスと同等のC++テンプレートを持っていた私が今やっているように、今日書かれた論文がActivator.CreateInstance(Type)を使うことを望んでいます。 – Berryl

関連する問題