所以,我正在尝试学习如何将我自己的表达式组合在一起,传递对象并编译以检索生成的结果,而我仍然试图准确理解我的对象实例在所有这些中的确切位置。
所以这就是我到目前为止阅读代码并单步执行
创建对象实例,表达式字符串和参数。
T SampleString = "Some String I have";
var operation= "it.Replace(@0, @1)";
var operationParameters = new [] { "e", "CLOWN"};
创建一个ParameterExpression对象,以指定将在
上执行操作的参数类型ParameterExpression[] parameters = new ParameterExpression[] { Expression.Parameter(typeof(T), "") };
使用ExpressionParser类,创建需要针对对象执行的表达式
ExpressionParser parser = new ExpressionParser(parameters, operation, operationParameters );
调用ExpressionParser Parse方法来检索生成的Expression,并将其传递给您想要的结果类型
var generatedExpression = parser.Parse(typeof(String));
现在调用Expression.Lamba,传递generatedExpression和项目
var StringReplaceresult = Expression.Lambda<Func<T,String> >(generatedExpression , parameters).Compile()(item);
我不确定上述内容是否正确,或者我的问题究竟在哪里开始。我知道我的编译失败了(5)。该消息是关于没有将正确数量的参数传递给Expression.Lamba方法。但我想知道问题是否真的存在,再次,我不确定我是否达到了60%,所以我很感激有人愿意在必要时纠正我的工作。
答案 0 :(得分:2)
我假设你正在使用Scott Guthrie描述的Dynamic Linq查询库:
如果是这样,我想你想要:
string sampleString = "some string I have";
var operation= "it.Replace(@0, @1)";
var operationParameters = new [] { "e", "CLOWN"};
Expression<Func<string, string>> expr = DynamicExpression.ParseLambda<string, string>(operation, operationParameters);
string result = expr.Compile().Invoke(sampleString);
当我在LinqPad中运行时,result
的值是“somCLOWN string I havCLOWN”
DynamicExpression.ParseLambda
允许您将参数类型指定为泛型类型参数,而不是通过显式创建ParameterExpression
数组来执行此操作。
ParseLambda<>
调用返回强类型Expression<TDelegate>
对象,它的Compile()
方法将基础lambda表达式编译成可执行代码,并将其作为正确类型的委托返回,然后可以调用。这意味着Invoke()
返回正确类型的对象(在这种情况下为string
),而不是必须转换的object
。因此,即使您从非强类型代码开始,您也会尽快恢复类型安全。
http://msdn.microsoft.com/en-us/library/bb345362.aspx
P.S。
在我的源代码中,ExpressionParser
是内部的,你顽皮的男孩/女孩; o)