Tôi muốn làm tương đương với:Làm cách nào để đánh giá biểu thức C#?
object result = Eval("1 + 3");
string now = Eval("System.DateTime.Now().ToString()") as string
Sau Biri s link, tôi đã đoạn này (sửa đổi để loại bỏ phương pháp lỗi thời ICodeCompiler.CreateCompiler()
:
private object Eval(string sExpression)
{
CSharpCodeProvider c = new CSharpCodeProvider();
CompilerParameters cp = new CompilerParameters();
cp.ReferencedAssemblies.Add("system.dll");
cp.CompilerOptions = "/t:library";
cp.GenerateInMemory = true;
StringBuilder sb = new StringBuilder("");
sb.Append("using System;\n");
sb.Append("namespace CSCodeEvaler{ \n");
sb.Append("public class CSCodeEvaler{ \n");
sb.Append("public object EvalCode(){\n");
sb.Append("return " + sExpression + "; \n");
sb.Append("} \n");
sb.Append("} \n");
sb.Append("}\n");
CompilerResults cr = c.CompileAssemblyFromSource(cp, sb.ToString());
if (cr.Errors.Count > 0)
{
throw new InvalidExpressionException(
string.Format("Error ({0}) evaluating: {1}",
cr.Errors[0].ErrorText, sExpression));
}
System.Reflection.Assembly a = cr.CompiledAssembly;
object o = a.CreateInstance("CSCodeEvaler.CSCodeEvaler");
Type t = o.GetType();
MethodInfo mi = t.GetMethod("EvalCode");
object s = mi.Invoke(o, null);
return s;
}
Tại sao điều này lại cần thiết? Tôi rất nghi ngờ rằng đây là thiết kế tốt nhất cho bất kỳ mục đích nào bạn có ý định. Nhiều khả năng có các cơ chế khác để tạo ra các kết quả mà bạn mong muốn mà không cần mở một lượng lớn các sâu (để bảo mật và bảo trì) đang đánh giá các đoạn mã trong thời gian chạy. – Wedge
Tôi muốn một cách nhanh chóng và bẩn để thêm xác nhận biểu thức vào một DSL tôi đã viết. Tôi kiểm soát các tập tin được cho ăn để đánh giá, do đó, các worms không bao giờ được mở;) Ngoài ra, tôi chỉ cho phép một biểu thức, không thêm bất kỳ Không gian tên/tham chiếu bất kỳ hội đồng. Điều này sẽ ngăn bản thân mình khỏi làm hại! –
Tôi thực hiện việc này trong các tình huống thử nghiệm. Tôi có một hội đồng thay đổi số phiên bản khi nó được cập nhật. Tôi muốn mã thử nghiệm của tôi bị "ràng buộc trễ" với hội đồng - để có thể nạp lắp ráp và gọi nó vào động. đây là một vấn đề phản chiếu đơn giản. Nhưng khi tôi muốn thực hiện một giao diện được chỉ định trong hội đồng, nó đòi hỏi biên dịch mã động, bởi vì giao diện chính nó si mạnh mẽ được đặt tên (với một số phiên bản). Tôi không thể có mã thực hiện IFoo v1.2 khi tôi muốn gọi v1.3. Biên dịch động sẽ giải quyết vấn đề này. – Cheeso