.net 我可以构建一个尾部调用递归优化表达式吗?

.net 我可以构建一个尾部调用递归优化表达式吗?,.net,recursion,expression-trees,tail-recursion,.net,Recursion,Expression Trees,Tail Recursion,我尝试在.NET4.0中构建一个尾部递归表达式 我可以构建它,但是编译后的方法没有对尾部调用进行优化,尽管指定了tailCall=true,生成的IL没有尾部。前缀指令 请告诉我如何构建尾部调用优化递归表达式 构建表达式如下所示 using System; using System.Linq.Expressions; namespace ConsoleApplication2 { public delegate int RecursiveFunc(RecursiveFunc funct

我尝试在.NET4.0中构建一个尾部递归
表达式

我可以构建它,但是编译后的方法没有对尾部调用进行优化,尽管指定了
tailCall=true
,生成的IL没有
尾部。
前缀指令

请告诉我如何构建尾部调用优化递归
表达式

构建表达式如下所示

using System;
using System.Linq.Expressions;

namespace ConsoleApplication2
{
    public delegate int RecursiveFunc(RecursiveFunc function, int acc, int n);

    internal class Program
    {
        private static void Main()
        {
            var funcParam = Expression.Parameter(typeof (RecursiveFunc));
            var accParam = Expression.Parameter(typeof (int));
            var nParam = Expression.Parameter(typeof (int));
            var constZero = Expression.Constant(0, typeof (int));

            var accumExpr = Expression.Add(accParam, nParam);
            var decrimentExpr = Expression.Decrement(nParam);

            var invokeExpr = Expression.Invoke(funcParam, funcParam, 
                accumExpr, decrimentExpr);

            var testExpr = Expression.Equal(nParam, constZero);
            var condExpr = Expression.Condition(testExpr, accParam, 
                invokeExpr);

            var lambda = Expression.Lambda<RecursiveFunc>(condExpr, 
                "TailCall", true, new[] {funcParam, accParam, nParam});

            var sumParam = Expression.Parameter(typeof (RecursiveFunc), 
                "Sum");

            var method = lambda.Compile();

            var ans = method(method, 0, 100);
            Console.WriteLine(ans);
        }
    }
}

以下工作围绕:

using System;
using System.Linq.Expressions;
using System.Reflection.Emit;

namespace ConsoleApplication2
{
    public delegate int RecursiveFunc(RecursiveFunc doCall, RecursiveFunc function, int acc, int n);

    internal class Program
    {
        private static void Main()
        {
            DynamicMethod dm = new DynamicMethod("DoInvokeWithTailCall", typeof(int), new Type[] { typeof(RecursiveFunc), typeof(RecursiveFunc), typeof(int), typeof(int) }, typeof(Program).Module);
            ILGenerator il = dm.GetILGenerator();
            il.Emit(OpCodes.Ldarg_1);
            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldarg_1);
            il.Emit(OpCodes.Ldarg_2);
            il.Emit(OpCodes.Ldarg_3);
            il.Emit(OpCodes.Tailcall);
            il.EmitCall(OpCodes.Callvirt, typeof(RecursiveFunc).GetMethod("Invoke"), null);
            il.Emit(OpCodes.Ret);
            RecursiveFunc doCall = (RecursiveFunc)dm.CreateDelegate(typeof(RecursiveFunc));

            var doCallParam = Expression.Parameter(typeof(RecursiveFunc));
            var funcParam = Expression.Parameter(typeof(RecursiveFunc));
            var accParam = Expression.Parameter(typeof(int));
            var nParam = Expression.Parameter(typeof(int));
            var constZero = Expression.Constant(0, typeof(int));

            var accumExpr = Expression.Add(accParam, nParam);
            var decrimentExpr = Expression.Decrement(nParam);

            //var invokeExpr = Expression.Invoke(funcParam, funcParam, funcParam, accumExpr, decrimentExpr); 
            var invokeExpr = Expression.Call(dm, doCallParam, funcParam, accumExpr, decrimentExpr);

            var testExpr = Expression.Equal(nParam, constZero);
            var condExpr = Expression.Condition(testExpr, accParam,
                invokeExpr);

            var lambda = Expression.Lambda<RecursiveFunc>(condExpr,
                "TailCall", true, new[] { doCallParam, funcParam, accParam, nParam });

            var method = lambda.Compile();

            var ans = method(doCall, method, 0, 100);
            Console.WriteLine(ans);
        }
    }
}
使用系统;
使用System.Linq.Expressions;
使用System.Reflection.Emit;
命名空间控制台应用程序2
{
公共委托int RecursiveFunc(RecursiveFunc doCall,RecursiveFunc函数,int acc,int n);
内部课程计划
{
私有静态void Main()
{
DynamicMethod dm=新的DynamicMethod(“DoInvokeWithTailCall”,typeof(int),new Type[]{typeof(RecursiveFunc),typeof(RecursiveFunc),typeof(int),typeof(int)},typeof(Program.Module);
ILGenerator il=dm.GetILGenerator();
il.Emit(操作码Ldarg_1);
il.Emit(操作码.Ldarg_0);
il.Emit(操作码Ldarg_1);
il.Emit(操作码Ldarg_2);
il.Emit(操作码Ldarg_3);
il.Emit(操作码Tailcall);
EmitCall(OpCodes.Callvirt,typeof(RecursiveFunc).GetMethod(“Invoke”),null;
发射(操作码Ret);
RecursiveFunc doCall=(RecursiveFunc)dm.CreateDelegate(typeof(RecursiveFunc));
var doCallParam=Expression.Parameter(typeof(RecursiveFunc));
var funcParam=表达式.参数(typeof(RecursiveFunc));
var accParam=Expression.Parameter(typeof(int));
var nParam=Expression.Parameter(typeof(int));
var constZero=表达式常数(0,typeof(int));
var accumExpr=Expression.Add(accParam,nParam);
var decrimentExpr=表达式。减量(NPRAM);
//var invokeExpr=Expression.Invoke(funcParam、funcParam、funcParam、accumExpr、DecrementExpr);
var invokeExpr=Expression.Call(dm、doCallParam、funcParam、accumExpr、decrementexpr);
var testExpr=表达式.Equal(nParam,constZero);
var condExpr=Expression.Condition(testExpr、accParam、,
调用eExpr);
var lambda=表达式.lambda(condExpr,
“TailCall”,真,新[]{doCallParam,funcParam,accParam});
var method=lambda.Compile();
var ans=方法(doCall,方法,0,100);
控制台写入线(ans);
}
}
}

您应该发布一些用于生成表达式的代码。很难说清楚。谢谢你的建议。我添加了一个示例代码,这个表达式生成了IL
using System;
using System.Linq.Expressions;
using System.Reflection.Emit;

namespace ConsoleApplication2
{
    public delegate int RecursiveFunc(RecursiveFunc doCall, RecursiveFunc function, int acc, int n);

    internal class Program
    {
        private static void Main()
        {
            DynamicMethod dm = new DynamicMethod("DoInvokeWithTailCall", typeof(int), new Type[] { typeof(RecursiveFunc), typeof(RecursiveFunc), typeof(int), typeof(int) }, typeof(Program).Module);
            ILGenerator il = dm.GetILGenerator();
            il.Emit(OpCodes.Ldarg_1);
            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldarg_1);
            il.Emit(OpCodes.Ldarg_2);
            il.Emit(OpCodes.Ldarg_3);
            il.Emit(OpCodes.Tailcall);
            il.EmitCall(OpCodes.Callvirt, typeof(RecursiveFunc).GetMethod("Invoke"), null);
            il.Emit(OpCodes.Ret);
            RecursiveFunc doCall = (RecursiveFunc)dm.CreateDelegate(typeof(RecursiveFunc));

            var doCallParam = Expression.Parameter(typeof(RecursiveFunc));
            var funcParam = Expression.Parameter(typeof(RecursiveFunc));
            var accParam = Expression.Parameter(typeof(int));
            var nParam = Expression.Parameter(typeof(int));
            var constZero = Expression.Constant(0, typeof(int));

            var accumExpr = Expression.Add(accParam, nParam);
            var decrimentExpr = Expression.Decrement(nParam);

            //var invokeExpr = Expression.Invoke(funcParam, funcParam, funcParam, accumExpr, decrimentExpr); 
            var invokeExpr = Expression.Call(dm, doCallParam, funcParam, accumExpr, decrimentExpr);

            var testExpr = Expression.Equal(nParam, constZero);
            var condExpr = Expression.Condition(testExpr, accParam,
                invokeExpr);

            var lambda = Expression.Lambda<RecursiveFunc>(condExpr,
                "TailCall", true, new[] { doCallParam, funcParam, accParam, nParam });

            var method = lambda.Compile();

            var ans = method(doCall, method, 0, 100);
            Console.WriteLine(ans);
        }
    }
}