2013-04-24 26 views
1

我需要針對這種情況。例如,我有這個類:如何從表達式設置屬性值?

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

在前端,用戶必須輸入值在該財產的機會:

Schema.Value = [表達這裏]

現在用戶可以調用返回字符串的函數,或者他可以連接來自不同模式的值,以將值分配給該特定模式值屬性。

如何做到這一點最好的方法?我覺得這很難解釋,但是如何保存該表達式(機制),然後在運行時計算它?

在此先感謝你們!

+1

如果您在運行時基於用戶定義的_expressions_執行此操作,請考慮使用表達式計算器,如[FLEE](http://flee.codeplex.com/)或[NCalc](http:// ncalc .codeplex.com /) – 2013-04-24 23:14:32

回答

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名稱空間。

你必須小心在表達式中公開了什麼類/方法,因爲它可能是一個很大的安全問題。您可以添加自己的類,添加外部程序集引用等,並且您無法控制正在執行的內容。