C# 转换方法签名&;修改方法体
我试图修改函数的表达式。 我想用返回相同值的函数替换函数输入参数。 其思想是转换:C# 转换方法签名&;修改方法体,c#,expression,roslyn,C#,Expression,Roslyn,我试图修改函数的表达式。 我想用返回相同值的函数替换函数输入参数。 其思想是转换:function(Foo-Foo){return Foo.ToString();} 使用函数(Func fooProvider){return fooProvider().ToString()} 实际上我甚至不想调用传递给我们的函数,而是直接使用函数体。 因此,真正的示例并没有得到一个Func作为输入,而是一个表达式 下面可以找到示例代码。 我假设我现在得到一个异常,因为我更改了函数的签名。 虽然这正是我想做的 一
function(Foo-Foo){return Foo.ToString();}
使用函数(Func fooProvider){return fooProvider().ToString()}
实际上我甚至不想调用传递给我们的函数,而是直接使用函数体。
因此,真正的示例并没有得到一个Func
作为输入,而是一个表达式
下面可以找到示例代码。
我假设我现在得到一个异常,因为我更改了函数的签名。
虽然这正是我想做的
一些代码:
节目
class Program
{
public static void Run()
{
Expression<Func<int, bool>> isOdd = number => (number % 2) == 1;
Expression<Func<string, int>> parseTextToNumber = text => Convert.ToInt32(text);
var vistor = new ReplaceExpressionVisitor(isOdd.Parameters[0], parseTextToNumber.Body);
var result = vistor.Visit(isOdd);
Expression<Func<string, bool>> textRepresentsOddNumber = result as dynamic;
//Expected something like this:
Expression<Func<string, bool>> expectedResult = text => (Convert.ToInt32(text) % 2) == 1;
}
}
以及错误消息:
System.InvalidOperationException:'从'VisitLambda'调用时,重写'System.Linq.Expressions.ParameterExpression'类型的节点'
必须返回同一类型的非null值。
或者,重写“VisitLambda”并将其更改为不访问此类型的子级。”
几个小时后,我确实发现了一些有用的东西 PS:不确定这是解决这个问题的最通用的还是最好的解决方案
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
public class Program
{
public static void Run()
{
Expression<Func<int, bool>> isOdd = number => (number % 2) == 0;
Expression<Func<string, int>> parseTextToNumber = text => Convert.ToInt32(text);
var visitor = new ReplaceExpressionVisitor(isOdd.Parameters[0], parseTextToNumber.Body);
var result = Expression.Lambda(visitor.Visit(isOdd.Body), parseTextToNumber.Parameters);
Expression<Func<string, bool>> textRepresentsOddNumber = result as dynamic;
//test:
var code = textRepresentsOddNumber.Compile();
Console.WriteLine(code.DynamicInvoke("0"));//writes false
Console.WriteLine(code.DynamicInvoke("1"));//writes true
}
}
private class ReplaceExpressionVisitor : ExpressionVisitor
{
private readonly Expression _oldValue;
private readonly Expression _newValue;
public ReplaceExpressionVisitor(Expression oldValue, Expression newValue)
{
_oldValue = oldValue;
_newValue = newValue;
}
public override Expression Visit(Expression node)
{
if (node == _oldValue)
return _newValue;
return base.Visit(node);
}
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用System.Linq.Expressions;
公共课程
{
公共静态无效运行()
{
表达式isOdd=number=>(number%2)==0;
表达式parseTextTonNumber=text=>Convert.ToInt32(text);
var visitor=new ReplaceExpressionVisitor(isOdd.Parameters[0],parseTextTonNumber.Body);
var result=Expression.Lambda(visitor.Visit(isOdd.Body),parseTextTonNumber.Parameters);
表达式textRepresentsOddNumber=结果为动态;
//测试:
var code=textrepreventsodnumber.Compile();
Console.WriteLine(code.DynamicInvoke(“0”);//写入错误
Console.WriteLine(code.DynamicInvoke(“1”);//写入true
}
}
私有类替换ExpressionVisitor:ExpressionVisitor
{
私有只读表达式_oldValue;
私有只读表达式_newValue;
公共替换ExpressionVisitor(表达式旧值、表达式新值)
{
_oldValue=oldValue;
_newValue=newValue;
}
公共重写表达式访问(表达式节点)
{
如果(节点==\u旧值)
返回_newValue;
返回基地访问(节点);
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
public class Program
{
public static void Run()
{
Expression<Func<int, bool>> isOdd = number => (number % 2) == 0;
Expression<Func<string, int>> parseTextToNumber = text => Convert.ToInt32(text);
var visitor = new ReplaceExpressionVisitor(isOdd.Parameters[0], parseTextToNumber.Body);
var result = Expression.Lambda(visitor.Visit(isOdd.Body), parseTextToNumber.Parameters);
Expression<Func<string, bool>> textRepresentsOddNumber = result as dynamic;
//test:
var code = textRepresentsOddNumber.Compile();
Console.WriteLine(code.DynamicInvoke("0"));//writes false
Console.WriteLine(code.DynamicInvoke("1"));//writes true
}
}
private class ReplaceExpressionVisitor : ExpressionVisitor
{
private readonly Expression _oldValue;
private readonly Expression _newValue;
public ReplaceExpressionVisitor(Expression oldValue, Expression newValue)
{
_oldValue = oldValue;
_newValue = newValue;
}
public override Expression Visit(Expression node)
{
if (node == _oldValue)
return _newValue;
return base.Visit(node);
}
}