8

ジェネリック型パラメーターで特定のオブジェクト型のインスタンスを受け入れるクラスがある状況があります。レイアウトは次のようなものです。

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("...");
    }
}

Handler<DiamondClass>しかし、明らかに暗黙的に にキャストしないため、これは機能しませんHandler<BaseClass>。次のように指定できます。

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>orを呼び出す必要がありますGetHandler<BaseClass>。そして、それは、型を知らなくても、列挙型に基づいて適切なハンドラーを返すメソッドを持つという目的を無効にします。Type次のように、オブジェクトを定義して渡すことができることを願っていました。

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

しかし、どうやら C# はそのような愚かさを許しません。私はこれをいくつかの異なる方法で行ってきました。それを行う方法があると思いたいのですが、困惑しています。


(私は実際にオブジェクトを返すことでこれを機能させましdynamicたが、型の安全性と Intellisense のサポートが失われるため、可能な限り回避したいと思います。)

4

1 に答える 1

10

これが共分散の出番です。共分散と反分散はインターフェイスとデリゲートでのみ機能するため、問題を解決するには、型パラメーターが共変であることを指定する新しいインターフェイスIHandler共変outとして定義するだけです。 :

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

共変型パラメーターを持つインターフェイスにより、そのメソッドは、型パラメーターで指定されたものよりも多くの派生型を返すことができます

それが動作します。詳細はこちら

于 2012-09-27T15:50:01.267 に答える