我如何为linq二进制表达式添加特定于类型的实现?

时间:2010-08-16 19:49:16

标签: c# linq lambda

我有一个相当简单的表达式解析器,它使用Linq.Expression命名空间。

输入类似于:(1 + 1),它找到左和右常量,并将operator char转换为ExpressionTypes枚举值,创建适当的表达式,编译并执行。

我真的希望能够进行字符串操作,(abc + def)会评估为abcdef,但是:

System.InvalidOperationException:没有为类型'System.String'和'System.String'定义二进制运算符Add

我将如何自己实施?

类似于ExpressionTypes.Concat的方法是理想的。

3 个答案:

答案 0 :(得分:2)

您必须自己创建MethodCallExpression,在本例中是针对静态方法string.Concat。 (这是编译器在编译此类代码时自行执行的操作)

答案 1 :(得分:1)

这里有一些代码演示了如何使用MethodInfo扩展二进制表达式的定义Add to串联字符串。

一个示例使用String类型中的现有Concat方法。

第二个示例在Program类型中使用自定义Concat方法(该类全部嵌入在其中):

private MethodInfo ConcatMethod = typeof(string).GetMethod("Concat", new Type[] { typeof(string), typeof(string) });
private MethodInfo ConcatMethod2 = typeof(Program).GetMethod("Concat", new Type[] { typeof(string), typeof(int) });

public static string Concat(string obj1, int obj2)
{
  return string.Concat(obj1, obj2.ToString());
}

private Expression SomeCode(string leftStr, string rightStr)
{
  Expression left = Expression.Constant(leftStr);
  Expression right = Expression.Constant(rightStr);

  return Expression.Add(left, right, ConcatMethod);
}

private Expression SomeCode(string leftStr, int rightInt)
{
  Expression left = Expression.Constant(leftStr);
  Expression right = Expression.Constant(rightInt);

  return Expression.Add(left, right, ConcatMethod2);
}

static void CheesyTest2()
{
  Program foo = new Program();
  Expression exp = foo.SomeCode("abc", "def");

  LambdaExpression lambdaExpression = Expression.Lambda(exp);
  Delegate func = lambdaExpression.Compile();
  object result = func.DynamicInvoke();
  Console.WriteLine(string.Format("Expression result: {0}", result));

  exp = foo.SomeCode("abc", 42);

  lambdaExpression = Expression.Lambda(exp);
  func = lambdaExpression.Compile();
  result = func.DynamicInvoke();
  Console.WriteLine(string.Format("Expression2 result: {0}", result));
}

答案 2 :(得分:0)

对于自定义运算符,它实际上是一个方法调用,因此您需要找到相应的方法并创建用于调用该方法的表达式树。没有与表达树一起工作太多,所以我很害怕我不能给你一个代码样本,但我希望这有帮助