簡體   English   中英

如何激活將操作作為其參數的泛型方法

[英]How to activate a generic method that takes an action as its parameter

當只能在運行時推斷類型時,您將如何使用反射來執行以下方法?

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

在日常使用中,通常:

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

因此,給定一個類型列表,我需要在上面的方法中將它們替換為T並調用。

這是我在變成膩子之前得到的地方:

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"))
}

(TheMethod()的參數類型是Action<OtherObject<T>> ,如上所述)

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

動作與AutoMapping<T>.Where("something")相同。在AutoMapping<T>.Where("something")

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

現在,為一堆類型做到這一點:)

您可以使用表達式解決此問題:

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

更新:完整的工作示例(粘貼到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);
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM