C# 如何从表达式中设置属性值?

C# 如何从表达式中设置属性值?,c#,dynamic,reflection,expression,C#,Dynamic,Reflection,Expression,我需要了解这个场景。例如,我有一门课: public class Schema { public string Value {get; set;} } 在前端,用户将有机会输入该属性的值: Schema.Value=[Expression here] 现在,用户可以调用返回字符串的函数,也可以连接来自不同模式的值,将值分配给特定的模式值属性 最好的方法是什么?我发现这很难解释,但如何保存该表达式(机制),然后在运行时进行计算 提前谢谢各位 您可以使用该类在运行时计算表达式,或编写类似的脚

我需要了解这个场景。例如,我有一门课:

public class Schema
{
   public string Value {get; set;}
}
在前端,用户将有机会输入该属性的值:

Schema.Value=[Expression here]

现在,用户可以调用返回字符串的函数,也可以连接来自不同模式的值,将值分配给特定的模式值属性

最好的方法是什么?我发现这很难解释,但如何保存该表达式(机制),然后在运行时进行计算

提前谢谢各位

您可以使用该类在运行时计算表达式,或编写类似的脚本引擎。 下面是一个简单的测试,用于计算
DateTime
表达式:

[TestMethod]
public void ExecuteTest()
{
    CodeDomProvider provider = provider = CodeDomProvider.CreateProvider("CSharp");
    CompilerParameters cp = new CompilerParameters();
    cp.GenerateExecutable = false;
    cp.GenerateInMemory = true;
    cp.TreatWarningsAsErrors = false;
    string source = @"using System; namespace N { public class C { public static DateTime Execute() { return DateTime.Now.AddDays(10); } } }";
    CompilerResults cr = provider.CompileAssemblyFromSource(cp, source);
    if(cr.Errors.Count > 0)
    {
        foreach(CompilerError ce in cr.Errors)
        {
            Console.Out.WriteLine("  {0}", ce.ToString());
        }
        Assert.Fail("Compilation error(s).");
    }
    else
    {
        object obj = cr.CompiledAssembly.CreateInstance("N.C");
        MethodInfo mi = obj.GetType().GetMethod("Execute", BindingFlags.Public | BindingFlags.Static);
        var actual = (DateTime)mi.Invoke(obj, null);
        Assert.IsNotNull(actual);
        var expected = DateTime.Now.AddDays(10).Date;
        Assert.AreEqual(expected, actual.Date);
    }
}
此代码需要反射来发现
C
类和
Execute
方法。您需要导入
System.Reflection
System.CodeDom.Compiler
名称空间

您必须小心在表达式中公开哪些类/方法,因为这可能是一个很大的安全问题。您可以添加自己的类,添加来自外部程序集的引用,等等,但您无法控制正在执行的操作。

您可以使用该类在运行时计算表达式,或编写类似的脚本引擎。 下面是一个简单的测试,用于计算
DateTime
表达式:

[TestMethod]
public void ExecuteTest()
{
    CodeDomProvider provider = provider = CodeDomProvider.CreateProvider("CSharp");
    CompilerParameters cp = new CompilerParameters();
    cp.GenerateExecutable = false;
    cp.GenerateInMemory = true;
    cp.TreatWarningsAsErrors = false;
    string source = @"using System; namespace N { public class C { public static DateTime Execute() { return DateTime.Now.AddDays(10); } } }";
    CompilerResults cr = provider.CompileAssemblyFromSource(cp, source);
    if(cr.Errors.Count > 0)
    {
        foreach(CompilerError ce in cr.Errors)
        {
            Console.Out.WriteLine("  {0}", ce.ToString());
        }
        Assert.Fail("Compilation error(s).");
    }
    else
    {
        object obj = cr.CompiledAssembly.CreateInstance("N.C");
        MethodInfo mi = obj.GetType().GetMethod("Execute", BindingFlags.Public | BindingFlags.Static);
        var actual = (DateTime)mi.Invoke(obj, null);
        Assert.IsNotNull(actual);
        var expected = DateTime.Now.AddDays(10).Date;
        Assert.AreEqual(expected, actual.Date);
    }
}
此代码需要反射来发现
C
类和
Execute
方法。您需要导入
System.Reflection
System.CodeDom.Compiler
名称空间


您必须小心在表达式中公开哪些类/方法,因为这可能是一个很大的安全问题。您可以添加您自己的类,从外部程序集添加引用等,并且您无法控制正在执行的内容。

如果您根据用户定义的表达式在运行时这样做,那么考虑使用表达式计算器,或者如果您在基于用户定义表达式的运行时这样做,然后考虑使用类似于