Как бы я добавил специфичные для типа реализации в бинарные выражения linq? - PullRequest
0 голосов
/ 16 августа 2010

У меня есть довольно простой анализатор выражений, который использует пространство имен Linq.Expression.

Входные данные примерно такие: (1 + 1), он находит левую и правую константы и преобразует оператор char в значение перечисления ExpressionTypes, создает соответствующее выражение, компилирует и выполняет.

Мне бы очень хотелось иметь возможность манипулировать строками, (abc + def) оценило бы, например, abcdef:

System.InvalidOperationException: бинарный оператор Add не определен для типов 'System.String' и 'System.String'

Как бы я сам реализовал это?

Было бы идеально, если бы это было что-то вроде эквивалента ExpressionTypes.Concat.

Ответы [ 3 ]

2 голосов
/ 16 августа 2010

Вы должны сами создать выражение MethodCallExpression, которое в данном случае предназначено для статического метода string.Concat. (Это то, что компилятор делает сам, когда вы компилируете такой код)

1 голос
/ 27 июля 2011

Вот некоторый код, который демонстрирует использование MethodInfo для расширения определения двоичного выражения Добавить в конкатенацию строк.

Один пример использует существующий метод Concat в типе String.

ВторойВ примере используется пользовательский метод Concat в типе Program (класс, в который все это встроено):

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));
}
0 голосов
/ 17 августа 2010

Для пользовательских операторов это фактически вызов метода, поэтому вам нужно найти соответствующий метод и создать дерево выражений для вызова этого метода.Я не слишком много работаю с деревьями выражений, так что я боюсь, я не могу дать вам пример кода, но я надеюсь, что это поможет

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...