C# - 从用户输入字符串动态创建函数体
C# - Dynamically create function body from user input string
我正在尝试创建一个 C# 程序,让用户通过在文本框中输入文本来提供函数的实现。我提供函数头(输入类型,输出类型),他们只需要提供实际实现即可。然后我存储该函数以供稍后调用。他们可能需要从 .NET Framework 中导入一些东西,但不需要导入它之外的东西。
我不关心安全性,这只是供内部使用的工具。
是否有在 .NET 中执行此操作的简单方法?
用法看起来像(需要实现 CompileUserFunction 函数,它接收一个 int 和 returns 一个对象):
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);
}
您可以为该任务使用代码生成库。
我建议您使用 Roslyn 脚本 API。我做过类似的任务——将字符串解析为委托。以下示例取自此 link:https://blogs.msdn.microsoft.com/csharpfaq/2011/12/02/introduction-to-the-roslyn-scripting-api/
您会发现更多示例
using Roslyn.Scripting.CSharp;
namespace RoslynScriptingDemo
{
class Program
{
static void Main(string[] args)
{
var engine = new ScriptEngine();
engine.Execute(@"System.Console.WriteLine(""Hello Roslyn"");");
}
}
}
还有其他代码生成工具和库:
- CodeDom - 一个旧的 .Net 代码生成框架。可能可以在这里使用,但更棘手。
https://docs.microsoft.com/en-us/dotnet/framework/reflection-and-codedom/using-the-codedom
- 有一些库用于将字符串转换为 Linq 表达式树,但现在似乎都过时了。
- 也可以通过 Reflection.Emit 创建动态方法,但它的级别非常低 - 您需要在 IL 指令中定义方法实现。
我正在尝试创建一个 C# 程序,让用户通过在文本框中输入文本来提供函数的实现。我提供函数头(输入类型,输出类型),他们只需要提供实际实现即可。然后我存储该函数以供稍后调用。他们可能需要从 .NET Framework 中导入一些东西,但不需要导入它之外的东西。
我不关心安全性,这只是供内部使用的工具。
是否有在 .NET 中执行此操作的简单方法?
用法看起来像(需要实现 CompileUserFunction 函数,它接收一个 int 和 returns 一个对象):
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);
}
您可以为该任务使用代码生成库。 我建议您使用 Roslyn 脚本 API。我做过类似的任务——将字符串解析为委托。以下示例取自此 link:https://blogs.msdn.microsoft.com/csharpfaq/2011/12/02/introduction-to-the-roslyn-scripting-api/ 您会发现更多示例
using Roslyn.Scripting.CSharp;
namespace RoslynScriptingDemo
{
class Program
{
static void Main(string[] args)
{
var engine = new ScriptEngine();
engine.Execute(@"System.Console.WriteLine(""Hello Roslyn"");");
}
}
}
还有其他代码生成工具和库:
- CodeDom - 一个旧的 .Net 代码生成框架。可能可以在这里使用,但更棘手。 https://docs.microsoft.com/en-us/dotnet/framework/reflection-and-codedom/using-the-codedom
- 有一些库用于将字符串转换为 Linq 表达式树,但现在似乎都过时了。
- 也可以通过 Reflection.Emit 创建动态方法,但它的级别非常低 - 您需要在 IL 指令中定义方法实现。