0
我在写流水线逻辑。这个想法是在实例中创建对象并在每种情况下执行Run方法。我可以用反射Activator.CreateInstance做旧的方式很容易,但在这种情况下性能很重要。LINQ动态创建对象没有反射(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 */
}
}
}
它仍然抛出异常“参数计数不匹配”,请尝试上面的控制台演示。感谢Damir的努力! – JBaltika
此外,如果我更改为下面的代码,它的作品。我正在用Expression.New(type)做的事情不对。 var newinstance = System.Activator.CreateInstance(type); func.DynamicInvoke(newinstance,arguments); – JBaltika
我试过我的示例,它的工作原理。你错过了我为'委托func'行做的改变 - 我在那里删除了一个参数。 问题的确是'Expression.New(type)':它是一个'Expression',但你需要提供一个实例作为lambda的参数。这就是为什么它可以使用'CreateInstance()'。它也可以像这样工作:'func.DynamicInvoke(Expression.Lambda(newExp).Compile().DynamicInvoke(),arguments)',但像上面所做的那样将它保留在单个表达式中效率更高。 –