3

因此,我正在尝试学习如何组合我自己的表达式、传递对象并编译以检索生成的结果,而我一直在努力了解我的对象实例在所有这些中的确切位置。

所以这就是我从阅读代码和逐步完成的过程中所得到的

  1. 创建您的对象实例、您的表达式字符串和参数。

    T SampleString = "Some String I have";
    var operation= "it.Replace(@0, @1)";
    var operationParameters = new [] { "e", "CLOWN"};
    
  2. 创建一个 ParameterExpression 对象以指定您的操作将对其执行的参数类型

    ParameterExpression[] parameters = new ParameterExpression[] { Expression.Parameter(typeof(T), "") };
    
  3. 使用 ExpressionParser 类,创建您需要针对您的对象执行的表达式

    ExpressionParser parser = new ExpressionParser(parameters, operation, operationParameters );
    
  4. 调用 ExpressionParser Parse 方法来检索生成的表达式,并传递给它你想要的结果类型

    var generatedExpression = parser.Parse(typeof(String));
    
  5. 现在调用 Expression.Lamba,将生成的Expression 和项目传递给它

    var StringReplaceresult = Expression.Lambda<Func<T,String> >(generatedExpression , parameters).Compile()(item);
    

我不太确定上述内容是否正确,或者我遇到的问题究竟从哪里开始。我知道我的编译失败(5)。该消息是关于没有将正确数量的参数传递给那里的 Expression.Lamba 方法。但我想知道这是否真的是问题所在,同样,我不确定我是否能达到 60%,所以我很感激有人会在必要时纠正我的上述工作。

4

1 回答 1

2

我假设您使用的是 Scott Guthrie 描述的动态 Linq 查询库:

http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx

如果是这样,我想你想要:

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

ps

在我拥有的源代码中,ExpressionParser是内部的,你这个淘气的男孩/女孩;o)

于 2013-09-11T15:58:48.900 回答