开发者

How would I add type specific implementations to linq binary expressions?

I have a fairly simple expression parser that uses the Linq.Expression namespace.

Input is something like: (1+1), it finds the left and right constants, and converts the operator char to an Expressi开发者_运维技巧onTypes enum value, creates the appropriate expression, compiles and executes.

I'd really like to be able to do string manipulations, (abc+def) would evaluate to abcdef for instance, however:

System.InvalidOperationException: The binary operator Add is not defined for the types 'System.String' and 'System.String'

How would I go about implementing this myself?

Something like the equavlant to an ExpressionTypes.Concat would be ideal.


You have to create the MethodCallExpression yourself, which in this case is for the static method string.Concat. (This is what the compiler does itself when you compile such code)


Here's some code that demonstrates using MethodInfo to extend the definition of the binary expression Add to concatenation of strings.

One example uses the existing Concat method in the String type.

The second example uses a custom Concat method in the Program type (the class this is all embedded in):

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));
}


For custom operators it's actually a method call so you need to find the corresponding method and create the expression tree for calling that method. Haven't work much with expression trees so im affraid I can't give you a code sample but I hope this Helps none the less

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜