我正在编写管道逻辑。我们的想法是在飞行中创建对象的实例,并在每种情况下执行方法Run方法。我可以用反射Activator.CreateInstance做旧方法很容易,但在这种情况下性能很重要。
我看了很多代码示例和教程,我认为我正确地使用了Lambda表达式。我只能弄清楚调用部分。提前谢谢。
namespace Pipelines
{
using System;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
public interface IProcessor
{
string Name { get; set; }
}
public interface IAspNetMembershipId : IProcessor
{
Guid? Id { get; set; }
}
public class ProcessorOne
{
public void Run(IProcessor args)
{
/* Do Something */
}
}
public class ProcessorTwo
{
public void Run(IAspNetMembershipId args)
{
/* Do Something */
}
}
public class Program
{
static void Main(string[] args)
{
var arguments = new AspNetMembershipId() { Name = "jim" };
/* Pipeline1 Begin */
Type type = typeof(ProcessorOne);
NewExpression newExp = Expression.New(type);
var p1 = Expression.Parameter(newExp.Type, "ProcessorOne");
var p2 = Expression.Parameter(typeof(IProcessor), "args");
MethodInfo methodInfo = (from method in newExp.Type.GetMethods() where method.Name.StartsWith("Run") select method).First();
var invokeExpression = Expression.Call(p1, methodInfo, p2);
Delegate func = Expression.Lambda(invokeExpression, p1, p2).Compile();
/* Throws an exception. This not correct! */
func.DynamicInvoke(newExp, arguments);
/* or */
func.DynamicInvoke(arguments);
/* Pipeline2 Begin */
}
}
}
答案 0 :(得分:0)
这应该有效:
var arguments = new AspNetMembershipId() { Name = "jim" };
/* Pipeline1 Begin */
Type type = typeof(ProcessorOne);
NewExpression newExp = Expression.New(type);
var p2 = Expression.Parameter(typeof(IProcessor), "args");
MethodInfo methodInfo = (from method in newExp.Type.GetMethods()
where method.Name.StartsWith("Run")
select method).First();
var invokeExpression = Expression.Call(newExp, methodInfo, p2);
Delegate func = Expression.Lambda(invokeExpression, p2).Compile();
/* Doesn't throw exception any more */
func.DynamicInvoke(arguments);
请注意,我已将newExp
直接提供给invokeExpression,并将arguments
作为唯一参数。