Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/299.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# 转换方法签名&;修改方法体_C#_Expression_Roslyn - Fatal编程技术网

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