简体   繁体   中英

C# - Dynamically create function body from user input string

I am trying to create a C# program that lets user's provide an implementation for for a function by inputting text into a text box. I provide the function header (input types, output type), they just need to provide actual implementation. I then store that function to call later. They might need to import something from the .NET framework, but nothing outside of it.

I don't care about security, this is just for a tool for internal use.

Is there an easy way to do this in .NET?

The usage would look something like (need to implement the CompileUserFunction function, which takes in an int and returns an object):

Func<int, object> CreateUserFunction(string input) {
    Func<int, object> userFunc = CompileUserFunction(input);
    return (i) => userFunc(i);
}

public void DoSomething() {
    List<Func<int, object>> userFuncs = new List<Func<int, object>>();

    string userInput = @"DateTime t = DateTime.Now; 
                         t.AddDays(i);
                         return t;";

    userFuncs.Add(CreateUserFunction(userInput));
    userFuncs.Add(CreateUserFunction("return i;"));
    userFuncs.Add(CreateUserFunction("i = i * 5; return i;"));
    var result = userFuncs[0](5);
}

You can use code generation libs for that task. I advice you to use Roslyn scripting API. I have done a similar task - parsing a string into delegate with it. The following example is taken from this link: https://blogs.msdn.microsoft.com/csharpfaq/2011/12/02/introduction-to-the-roslyn-scripting-api/ You will find there more examples

using Roslyn.Scripting.CSharp;

namespace RoslynScriptingDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            var engine = new ScriptEngine();
            engine.Execute(@"System.Console.WriteLine(""Hello Roslyn"");");
        }
    }
}

There are other code generation tools and libs:

  • CodeDom - an old .Net code generation Framework. Probably can be used here but is more tricky. https://docs.microsoft.com/en-us/dotnet/framework/reflection-and-codedom/using-the-codedom
  • There were some libraries which were used to convert strings to Linq Expression trees, but it all seems to be outdated now.
  • There is also a possibility to create a Dynamic Method via Reflection.Emit but it is very low level - you need to define method implementation in IL instructions.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM