How to use function from my code in runtime-compiled code?

169 views Asked by At

I know that I can compile function at runtime and use code copied from this CodeProject article:

   public static MethodInfo CreateFunction(string function)
   {
       string code = @"
           using System;
               
           namespace UserFunctions
           {                
               public class BinaryFunction
               {                
                   public static double Function(double x, double y)
                   {
                       return func_xy;
                   }
               }
           }
       ";
   
       string finalCode = code.Replace("func_xy", function);
   
       CSharpCodeProvider provider = new CSharpCodeProvider();
       CompilerResults results = >provider.CompileAssemblyFromSource(new CompilerParameters(), finalCode);
   
       Type binaryFunction = results.CompiledAssembly.GetType("UserFunctions.BinaryFunction");
       return binaryFunction.GetMethod("Function");
   }

But if I have function in my code,

Func<int, int, int> SomeFunction = (int1, int2)=>
{
    return int1 + int2;
}

how can I use it in generated code so I get something like this:

public static Func<int, int, int> SomeFunction = (int1, int2)=>
{
    return int1 + int2;
}

public static MethodInfo CreateFunction()
{
    string code = @"
        using System;
            
        namespace UserFunctions
        {                
            public class BinaryFunction
            {                
                public static double Function(double x, double y)
                {
                    return SomeFunction(x, y);
                }
            }
        }
    ";

    CSharpCodeProvider provider = new CSharpCodeProvider();
    CompilerResults results = provider.CompileAssemblyFromSource(new CompilerParameters(), code);

    Type binaryFunction = results.CompiledAssembly.GetType("UserFunctions.BinaryFunction");
    return binaryFunction.GetMethod("Function");
}

Update

I managed to do what I wanted with this code

using Microsoft.CSharp;
using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApp2
{
    public static class Program
    {
        /// <summary>
        /// Главная точка входа для приложения.
        /// </summary>
        [STAThread]
        static void Main()
        {
            var function = CreateFunction();
            var res = function.Invoke(null, new object[] { 1d,2d});
            Console.WriteLine(res);
        }

        public static double SomeFunction(double int1, double int2)
        {
            return int1 + int2;
        }


        public static MethodInfo CreateFunction()
        {
            string code = @"
                    using System;
                    using WindowsFormsApp2;
            
                    namespace UserFunctions
                    {                
                        public class AddFunction
                        {                
                            public static double Function(double x, double y)
                            {
                                return (double)typeof(Program).GetMethod(""SomeFunction"").Invoke(null, new object[] { x, y }); 
                            }
                        }
                    }
                ";

            CSharpCodeProvider provider = new CSharpCodeProvider();

            CompilerParameters options = new CompilerParameters();
            options.GenerateExecutable = false;
            options.GenerateInMemory = true;
            options.ReferencedAssemblies.Add(Assembly.GetExecutingAssembly().Location);
            
            CompilerResults results = provider.CompileAssemblyFromSource(options, code);

            Type binaryFunction = results.CompiledAssembly.GetType("UserFunctions.AddFunction");
            return binaryFunction.GetMethod("Function");
        }
    }
}

Is there better/easier way to do this?

0

There are 0 answers