mardi 11 octobre 2016

Creation recursive method in runtime

How can I create recursive method in runtime in .Net? Below is my first attempt to create factorial method dynamically:

    static void Main()
    {
        var rec_funcs = RecurFuncs();
        Console.WriteLine("Fact result: {0}", rec_funcs.GetMethod("Fact").Invoke(null, new object[] { 10 }));
        Console.ReadKey();
    }

    public static Type RecurFuncs()
    {

        TypeBuilder FuncBuilder = null;
        ModuleBuilder RecursiveFunctionsModule = null;
        {
            //  Dynamic assembly creation
            AppDomain myDomain = Thread.GetDomain();
            AssemblyName myAsmName = new AssemblyName() { Name = "RecursiveFunctionsAssembly" };
            AssemblyBuilder myAsmBuilder = myDomain.DefineDynamicAssembly(myAsmName, AssemblyBuilderAccess.RunAndSave);
            RecursiveFunctionsModule = myAsmBuilder.DefineDynamicModule("RecursiveFunctionsModule", "RecursiveFunctions.dll");
            FuncBuilder = RecursiveFunctionsModule.DefineType("RecursiveFunctions", TypeAttributes.Public);

        }
        {
            //  Fact
            MethodBuilder FactMethod = FuncBuilder.DefineMethod("Fact", MethodAttributes.Public | MethodAttributes.Static, typeof(int), new Type[] { typeof(int) });
            var n_param = Expression.Parameter(typeof(int), "n");
            var method_body = Expression.IfThenElse(
                Expression.Equal(n_param, Expression.Constant(0)),
                Expression.Constant(1),
                Expression.Multiply(
                    n_param,
                    Expression.Call(
                        RecursiveFunctionsModule.GetType("RecursiveFunctions").GetMethod("Fact"),
                        Expression.Subtract(
                            n_param,
                            Expression.Constant(1)))));

            LambdaExpression lambda = Expression.Lambda(method_body, n_param);
            lambda.CompileToMethod(FactMethod);
        }
        Type RecursiveFunctionsType = FuncBuilder.CreateType();

        return RecursiveFunctionsType;
    }

In runtime I get following exception's message:

The invoked member is not supported before the type is created.

As I understood, c# expressions require ready generated type to use (at the moment of usage RecursiveFunctions type is not created)





Aucun commentaire:

Enregistrer un commentaire