2

厳しいジェネリック制約を持つ 2 つの型パラメーターを持つジェネリック インターフェイスと、さまざまな組み合わせのいくつかの実装があります。

public interface IResolver<TIn, TOut> where ... {...}

既知の実装のインスタンスを格納する (静的) リゾルバー ファクトリを作成し、次のように処理するだけです。

public static ResolverFactory{

   public static IResover<TIn, TOut>  GetResolver<TIn, TOut> where ... ()
   {
       //access some storage dictionary to return the correctly typed instance
   }
}

IResover<Entity1, Entity2>と の両方を格納するようなコンテナを作成するにはどうすればよいIResolver<Entity3, Entity4>ですか?

私が考えることができる1つのオプションは、次のような別の非ジェネリック「マーカー」インターフェースを使用することです。

public interface IResolver {} 
public interface IResolver<TIn, TOut> : IResolver where .... 
{...}

と使用

Dictionary<Type, Dictionary <Type, IResolver>> storage;

public RegisterResolver(IResolver resolver)
{
   //add to storage - how?
}

しかし、このシナリオは基本的に、ジェネリック パラメーターに課せられた制約を無効にします。また、 を追加する場合IResolver、 のジェネリック型を取得することIResolver<TIn, TOut>は多かれ少なかれ不可能です。

これに対するより良い解決策はありますか?

4

2 に答える 2

3

問題がどこにあるのかわからないため、あなたの質問には明らかに欠けているものがあるかもしれません。

IResolver<TIn, TOut>まず、制約付きのインターフェイスを宣言します。

public interface IResolver<TIn, TOut>
    where TIn : Stream 
{

}

次に、とメソッドResolverFactoryの両方によって制約が適用されるを作成します。ストレージはクラスの外部に公開されないため、オブジェクトが実際に格納される方法は重要ではありません。カプセル化により一貫性が維持されます。RegisterResolverGetResolver

public static class ResolverFactory
{
    private static Dictionary<Type, object> storage = new Dictionary<Type, object>();

    public static void RegisterResolver<TIn, TOut>(IResolver<TIn, TOut> resolver) where TIn : Stream 
    {
        storage[typeof(IResolver<TIn, TOut>)] = resolver;
    }

    public static IResolver<TIn, TOut> GetResolver<TIn, TOut>() where TIn : Stream
    {
        return storage[typeof(IResolver<TIn, TOut>)] as IResolver<TIn, TOut>;
    }
}
于 2013-10-10T12:18:28.143 に答える
2

KooKiz の回答と同様ですが、キャスティングも辞書もありません。使い方は似ています。

//Rather than:
var res = ResolverFactory.GetResolver<Stream, Hat>();
//You Do:
var res = ResolverFactory<Stream, Hat>.GetResolver();

汎用パラメーターを移動しただけで、汎用制約をより少ない場所で定義できるという利点が追加されました。

public interface IResolver<TIn, TOut>
    where TIn : Stream
{
}

//Still static, but now there is one per TIn,TOut pair
//so no need for dictionary, so also no need for casting.
public static class ResolverFactory<TIn, TOut> where TIn : Stream
{
    private static IResolver<TIn, TOut> _resolver;

    public static void RegisterResolver(IResolver<TIn, TOut> resolver)
    {
        _resolver = resolver;
    }

    public static IResolver<TIn, TOut> GetResolver()
    {
        return _resolver;
    }
}


internal class Program
{
    private static void Main(string[] args)
    {
        ResolverFactory<Stream, Hat>.RegisterResolver(new MyStreamToHatResolver());

        var res = ResolverFactory<Stream, Hat>.GetResolver();
    }
}
于 2013-10-10T12:40:26.130 に答える