2012-09-27 4 views
7

ジェネリックタイプのパラメータで特定のオブジェクトタイプのインスタンスを受け入れるクラスがある場合があります。私はは、入力時に型を定義せずにHandler<DiamondClass>またはHandler<BaseClass>のインスタンスを返すメソッドを作成できるようにしたいタイプを知らないジェネリックを返す

public abstract BaseClass { ... } 
public DiamondClass : BaseClass { ... } 
public SilverClass : BaseClass { ... } 

public Handler<T> where T : BaseClass { ... } 

:レイアウトは、このようなものです。どうやらHandler<DiamondClass>Handler<BaseClass>に暗黙的にキャストしないので、

public Handler<BaseClass> GetHandler(HandlerType type) 
{ 
    switch(type) 
    { 
     case HandlerType.Diamond: return new Handler<DiamondClass>(); 
     case HandlerType.Silver: return new Handler<SilverClass>(); 
     default: throw new InvalidOperationException("..."); 
    } 
} 

しかし、これは動作しません:私はこれらの線に沿って何かをしようとしました。私はこのようにそれを指定することができます。

public Handler<T> GetHandler<T>(HandlerType type) where T : BaseClass 
{ 
    switch(type) 
    { 
     case HandlerType.Diamond: return (Handler<T>)new Handler<DiamondClass>(); 
     case HandlerType.Silver: return (Handler<T>)new Handler<SilverClass>(); 
     default: throw new InvalidOperationException("..."); 
    } 
} 

しかし、今、私はGetHandler<DiamondClass>またはGetHandler<BaseClass>を呼び出す必要があります。そして、型を知らなくても、列挙型に基づいて適切なハンドラを返すメソッドを持つという目的を破ります。

Type objType = typeof(DiamondClass); 
var handler = Handler<objType>(); 

しかし、どうやらC#が愚かのようなものを許可しません:私はTypeオブジェクトを定義し、そのように、それを渡すことができることを期待しました。私はこれをいくつかの方法で行ってきました。それを行う方法はあると思っていますが、私は困惑しています。


(私は実際にdynamicオブジェクトを返すことで、この作業を取得しましたが、それはどのようなタイプの安全性とインテリセンスのサポートを失うように私は、全く可能であればそれを避けるためにしたいと思います。)

+0

です。varハンドラ= Handler (); 'の何が問題なのですか、私はあなたが解決しようとしている問題は何も見ていません。 – CaffGeek

+3

ジェネリックメソッドの内部で型をチェックする必要がある場合、私はいつもそのようなメソッドの有用性に疑問を呈します。 –

+0

@RobA説明のために例を単純化したことに留意してください。問題の一部は、それがユーザーコントロールに属したいと思っていて、デザイナーを殺してしまうため、それを一般的なものとして定義できません。 – KChaloux

答えて

9

ですの共分散が出てくると、共分散とコントラバリエーションはインターフェイスと代理人だけで動作するので、あなたの問題を解決するためにIHandlerとしてoutとタイプパラメータ共変種である:

public interface IHandler<out T> where T : BaseClass 
{ 
} 

共変の型パラメータを有しているインターフェースは、それが動作するタイプパラメータ

によって指定されたものよりも多くの派生型を返すために、その方法を可能にします。さらに詳しい情報はhere

+2

+1 the linkyyyy – JonH

+0

ねえ、私は、タイプでそれをすることができるのか分からなかった!クールな豆。私はこのことを学ぶのが大好きです。編集:ちょうどそれを試してみました。あなたは命の恩人です。それは私がやらなければならないと思った以上にコンセプトの方法を単純化しました。私はそれがなぜ子どもを基盤の一種として受け入れないのだろうと思っていました。 – KChaloux

+0

@KChaloux:あなたが正しくあなたを理解すれば、この物は単にINTERFACEとDELEGATEと一緒に働くからですか? *子どもがベースの一種であることを意味するのは何ですか? –

関連する問題