1

C#に関連- 「タイプの切り替え」にこれよりも優れた代替手段はありますか?

「型をオンにする」必要があります。 type のパラメーターが与えられたT場合、フォームのメソッドを見つけて実行しますvoid Method (T param)

これは switch ステートメントまたは で解決できますがDictionary<Type, Action>、そのようなシナリオで必要なキャストは避けたいと思います。

上記の(または同様の)質問で言及されている次のアプローチが見つかりませんでした:

  1. コレクションとして機能する静的ジェネリック型を作成します。

    public static class Commands<T> {
      public static Action<T> Handler;
    }
    
  2. タイプ セーフな辞書のようなそのタイプを使用するリポジトリを作成します。

    public class CommandRepository {
        public void Register<T>(Action<T> handler) {
            Commands<T>.Handler = handler;
        }
    
        public void Run<T>(T parameter) {
            // null checks etc.
            Commands<T>.Handler(parameter);
        }
    }
    
  3. 使用例:

    public void CreateUser(CreateUserParams p) {
        Console.WriteLine("Creating " + p.Name);
    }
    
    // ...
    var repo = new CommandRepository();
    
    repo.Register<CreateUserParams>(CreateUser);
    repo.Register<DeleteUserParams>(DeleteUser);
    
    repo.Run(new CreateUserParams { Name = "test" });
    repo.Run(new DeleteUserParams { Name = "test" });
    

前述のように、同じ動作を の で実現できますがDictionary<Type, Action>ComandRepositoryメソッド パラメーターをキャストするか、 の代わりにインターフェイスを使用する場合は、ディクショナリ項目を取得Actionした後に にキャストする必要があります。IFoo<T>

私の質問は次のとおりです:そのようなジェネリック型を (乱用) 使用してもよいですか ( の可能な値が多数ある場合T)?

(おまけの質問) もしダメなら、なぜダメなのですか? これによってどのようなコストやマイナスの影響が生じるでしょうか?

最後の注意: これは型階層またはインターフェイスでは機能しないことを認識しています。タイプTは正確に一致する必要がありますが、私のシナリオではこれで問題ありません。

編集: JSON シリアライザーであるJilもこのパターンに依存していることがわかりました。TypeCacheタイプのオブジェクトをシリアル化するデリゲートを格納するタイプを参照してくださいT(コードをざっと読んで理解した限り)。これTypeCacheは大量の型を格納するので、パターンは一般的に問題ないと思います。

型またはその静的メンバーをガベージ コレクションする必要があるかどうか、または考慮する必要がある他のパフォーマンスへの影響があるかどうかを知ることは、依然として興味深いでしょう。

4

2 に答える 2

1

あなたが提案するアプローチは実行可能ですが、リポジトリが事実上シングルトンであるという欠点があります。シングルトンのように動作しないリポジトリが必要になった場合は、ConditionalWeakTable[1] タイプが役立つことがあります。それらのいずれかを使用する際の秘訣は、関心のあるタイプごとにConditionalWeakTable、オブジェクトをそのタイプに関連付けられているもの (存在する場合) にマップするシングルトンがあることです。このクラスは .NET 4.0 でのみ使用できますが、いくつかの素晴らしい機能を実行できます。

[1] http://msdn.microsoft.com/en-us/library/dd287757.aspx

例として、 aとOutTypeKeyedDictionaryをサポートする型が必要だとします。のシングルトン インスタンスを保持する各クラスの静的クラス ファミリを使用できます。実際にはフィールドはありません(!); むしろ、各インスタンスは、キーとして使用される ID トークンとして純粋に使用されます。ちなみに、クラスが名前空間ではなく名前空間にあるのは、 などで頻繁に使用されるためです。SetValue<T>(T Value)bool TryGetValue<T>(out T Value)OutputMappers<T>ConditionalWeakTable<OutTypeKeyedDictionary, T>OutTypeKeyedDictionaryConditionalWeakTableCompilerServicesCollectionsExpandoObject

于 2013-08-27T16:11:00.000 に答える