2011-09-14 7 views
17

タイプを実行時にしか推論できない場合に、リフレクションを使用して次のメソッドを実行する方法を教えてください。日常的な使用でアクションをパラメータとして取るジェネリックメソッドをアクティブにする方法

MainObject.TheMethod<T>(Action<OtherObject<T>>) 

、通常:だから

mainObject.Method<Message>(m => m.Do("Something")) 

、タイプのリストを考えると、私は上記の方法でTのためにそれらを代用して起動する必要があります。

私はパテになってまで私の頭の前だ場所です:明確にするために、私はタイプのリストを持っていると私はそれぞれにOtherObjectの同じ既知の方法を実行したい:

var mapped = typeof(Action<OtherObject<>>).MakeGenericType(t.GetType()); 
Activator.CreateInstance(mapped, new object[] { erm do something?}); 

typeof(OtherObject) 
    .GetMethod("TheMethod") 
    .MakeGenericMethod(t.GetType()) 
    .Invoke(model, new object[] { new mapped(m => m.Do("Something")) }); 

更新。擬似コード:

foreach(var t in types) 
{ 
    mainObject.TheMethod<t>(mo => mo.Do("Something")) 
} 

FluentNHibernate.Automapping.AutoPersistenceModel Override<T>(System.Action<AutoMapping<T>> populateMap) 

アクションすぐAutoMapping<T>.Where("something")

model.Override<Message>(m => m.Where("DeletedById is null")) 

の同じである(TheMethodのパラメータのタイプは、()上述のようAction<OtherObject<T>>です)

+2

は、アクションのボディは 'すなわち、常に' m.Do( "何か")、常に同じですか? –

+0

はい、上にいくつかの説明が追加されました –

+0

私の答えはあなたを助けませんか? –

答えて

3

あなたは式を使ってこれを解決できます:

foreach(var t in types) 
{ 
    var mapped = typeof(AutoMapping<>).MakeGenericType(t); 

    var p = Expression.Parameter(mapped, "m"); 
    var expression = Expression.Lambda(Expression.GetActionType(mapped), 
             Expression.Call(p, mapped.GetMethod("Do"), 
             Expression.Constant("Something")), p); 

    typeof(SomeOtherObject).GetMethod("TheMethod").MakeGenericMethod(t) 
          .Invoke(model, new object[] { expression.Compile() }); 
} 

UPDATE:完全な作業例(LINQPadに貼り付けると、それを実行する):

void Main() 
{ 
    var types = new []{typeof(string), typeof(Guid)}; 
    SomeOtherObject model = new SomeOtherObject(); 
    foreach(var t in types) 
    { 
     var mapped = typeof(AutoMapping<>).MakeGenericType(t); 

     var p = Expression.Parameter(mapped, "m"); 
     var expression = Expression.Lambda(
          Expression.GetActionType(mapped), 
          Expression.Call(p, mapped.GetMethod("Do"), 
          Expression.Constant("Something")), p); 

     typeof(SomeOtherObject).GetMethod("TheMethod") 
           .MakeGenericMethod(t) 
           .Invoke(model, 
             new object[] { expression.Compile() }); 
    } 
} 

class AutoMapping<T> 
{ 
    public void Do(string p) 
    { 
     Console.WriteLine(typeof(T).ToString()); 
     Console.WriteLine(p); 
    } 
} 

class SomeOtherObject 
{ 
    public void TheMethod<T>(Action<AutoMapping<T>> action) 
    { 
     var x = new AutoMapping<T>(); 
     action(x); 
    } 
} 
+0

ご返事遅れて申し訳ありません。これを適所に置いてください。私はこれで期待される型を得ています:var mapped = typeof(Action >)。MakeGenericType(t); –

+0

あなたはどの.NETバージョンを使用していますか?そして、私に完全なエラーメッセージを教えてください。これはコンパイルエラーだと思いますか? –

+0

@BobTodd:更新されたコードをご覧ください。これを試して。 –

関連する問題