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

时间:2013-04-24 22:50:59

标签: c# dynamic reflection expression

我需要针对这种情况进行定位。例如,我有这个类:

public class Schema
{
   public string Value {get; set;}
}

在前端,用户将有机会输入该属性的值:

Schema.Value = [此处表达式]

现在用户可以调用返回字符串的函数,或者他可以连接不同模式的值,以将值赋给该特定模式值属性。

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

先谢谢你们!

1 个答案:

答案 0 :(得分:1)

您可以使用CodeDomProvider类在运行时评估表达式,或者使用CS-Script等脚本引擎。 这是一个简单的测试,用于评估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.ReflectionSystem.CodeDom.Compiler名称空间。

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