2013-04-06 5 views
7

(//編集:consequentily番号の項目の配列が、私は昨日、私の辞書をやったのと同じ方法でありますよう完全にばかげている):ジェネリックAction <>タイプをパラメータ数で動的に取得するより洗練された方法ですか?私はこれをやっている瞬間

Dictionary<int, Type> genericMap = new Dictionary<int, Type> 
     { 
      { 0, typeof(Action) }, 
      { 1, typeof(Action<>) }, 
      { 2, typeof(Action<,>) }, 
      { 3, typeof(Action<,,>) }, 
      { 4, typeof(Action<,,,>) }, 
      { 5, typeof(Action<,,,,>) }, 
      { 6, typeof(Action<,,,,,>) }, 
      { 7, typeof(Action<,,,,,,>) }, 
      { 8, typeof(Action<,,,,,,,>) }, 
     }; 

そしてどこか。 ..

var parms = meth.GetParameters(); 
dType = genericMap[parms.Length].MakeGenericType(parms.Select(p => p.ParameterType).ToArray()); 

ここで、methはMethodInfoです。

もっとエレガントな方法がありますか?または、このようなマップを定義して、適切なアクション<>型を動的に取得する必要がありますか?

+0

目的を知ることは役に立ちます。あなたが解決しようとしているより大きな問題がより良いアイデアを与えられれば、より質の高い答えが得られるでしょう。 – konkked

答えて

10

EDIT:ところで

、あなたがExpression.GetActionTypeを知っていますか?

特定の型引数を持つ汎用System.Actionデリゲート 型を表すTypeオブジェクトを作成します。

そのメソッドを使用して、あなたが行うことができます:

dType = Expression.GetActionType(parms.Select(p => p.ParameterType).ToArray()); 

その他の方法:

var parms = meth.GetParameters(); 

int numArgs = parms.Length; 

if(numArgs == 0) 
{ 
    dType = typeof(Action); 
}  
else 
{ 
    var rawType = Type.GetType("System.Action`" + numArgs); 
    dType = rawType.MakeGenericType(parms.Select(p => p.ParameterType).ToArray()); 
} 

をしかし、実際にあなたのアプローチには何の問題も本当にありません。可能性のある明示的なものであることは、多くの場合反射になるより良い選択です。

また、ここではあなたのマップを構築するための別のファンシーな方法です:

typeof(Action).Assembly 
       .GetExportedTypes() 
       .Where(type => type.FullName.StartsWith("System.Action") 
            && type.IsSubclassOf(typeof(Delegate))) 
       .ToDictionary(type => type.GetGenericArguments().Length) 
+0

GetActionTypeはチャームのように機能します。どうもありがとう! –

1

あなたが代わりに辞書の配列を使用することができますが、それは実際には型の配列を使用して、インデックスとそれらにアクセスする、0から8まで番号を付けています。

+0

Aniの答えが私の問題を完全に解決するという事実を除けば、これは自己面白いことの古典的なケースです:明らかに、私は木々のために森を見逃してしまったことは明らかに急いでいました... ! –

関連する問題