Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何向linq二进制表达式添加特定于类型的实现?_C#_Linq_Lambda - Fatal编程技术网

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

C# 如何向linq二进制表达式添加特定于类型的实现?,c#,linq,lambda,C#,Linq,Lambda,我有一个相当简单的表达式解析器,它使用Linq.expression名称空间 输入类似于:(1+1),它查找左常量和右常量,并将运算符char转换为ExpressionTypes枚举值,创建适当的表达式,编译并执行 我真的希望能够进行字符串操作,(abc+def)将计算为abcdef,但是: System.InvalidOperationException:未为类型“System.String”和“System.String”定义二进制运算符Add 我将如何着手实施这一点呢 类似于表达式Type

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

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

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

System.InvalidOperationException:未为类型“System.String”和“System.String”定义二进制运算符Add

我将如何着手实施这一点呢


类似于表达式Types.Concat的EqualLant的东西是理想的。

您必须自己创建MethodCallExpression,在本例中,它是用于静态方法string.Concat的。(这是编译器在编译此类代码时自己所做的)

您必须自己创建MethodCallExpression,在本例中,它用于静态方法string.Concat。(这是编译器在编译此类代码时自己所做的)

对于自定义运算符,它实际上是一个方法调用,因此您需要找到相应的方法并创建用于调用该方法的表达式树。没有太多的表达式树的工作,所以我很抱歉,我不能给你一个代码示例,但我希望这对自定义操作符仍然有帮助,它实际上是一个方法调用,所以你需要找到相应的方法并创建表达式树来调用该方法。我对表达式树没有太多的了解,所以我很抱歉我不能给你一个代码示例,但我希望这对你仍然有帮助。下面是一些代码,演示如何使用MethodInfo扩展二进制表达式的定义,并将其添加到字符串的串联中

一个示例使用字符串类型中现有的Concat方法

第二个示例在程序类型中使用了一个自定义Concat方法(该方法都嵌入在该类中):


下面的一些代码演示了如何使用MethodInfo扩展二进制表达式的定义,并将其添加到字符串的串联中

一个示例使用字符串类型中现有的Concat方法

第二个示例在程序类型中使用了一个自定义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));
}