如何激活以动作作为参数的泛型方法
本文关键字:作作 参数 泛型方法 何激活 激活 | 更新日期: 2023-09-27 18:08:47
当类型只能在运行时推断时,您将如何使用反射来执行以下方法?
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")) });
Update:为了澄清,我有一个类型列表,我希望为每个类型执行相同的已知方法。伪代码:
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")
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);
}
}