¿Cómo puedo evaluar una expresión de C# dinámicamente?
Me gustaría hacer el equivalente a:
object result = Eval("1 + 3");
string now = Eval("System.DateTime.Now().ToString()") as string
Siguiendo el enlace de Biri , obtuve este fragmento (modificado para eliminar el método obsoleto 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;
}
Tema antiguo, pero considerando que este es uno de los primeros hilos que aparecen al buscar en Google, aquí hay una solución actualizada.
Puede utilizar la nueva API de secuencias de comandos de Roslyn para evaluar expresiones .
Si está utilizando NuGet, simplemente agregue una dependencia a Microsoft.CodeAnalysis.CSharp.Scripting . Para evaluar los ejemplos que proporcionó, es tan simple como:
var result = CSharpScript.EvaluateAsync("1 + 3").Result;
Obviamente, esto no hace uso de las capacidades asíncronas del motor de secuencias de comandos.
También puede especificar el tipo de resultado evaluado según lo previsto:
var now = CSharpScript.EvaluateAsync<string>("System.DateTime.Now.ToString()").Result;
Para evaluar fragmentos de código más avanzados, pasar parámetros, proporcionar referencias, espacios de nombres y demás, consulte la wiki vinculada anteriormente.
He escrito un proyecto de código abierto, Dynamic Expresso , que puede convertir expresiones de texto escritas usando una sintaxis de C# en delegados (o árbol de expresiones). Las expresiones de texto se analizan y transforman en árboles de expresión sin utilizar compilación ni reflexión.
Puedes escribir algo como:
var interpreter = new Interpreter();
var result = interpreter.Eval("8 / 2 + 2");
o
var interpreter = new Interpreter()
.SetVariable("service", new ServiceExample());
string expression = "x > 4 ? service.aMethod() : service.AnotherMethod()";
Lambda parsedExpression = interpreter.Parse(expression,
new Parameter("x", typeof(int)));
parsedExpression.Invoke(5);
Mi trabajo se basa en el artículo de Scott Gu http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx .
Si desea específicamente invocar código y ensamblados en su propio proyecto, recomendaría utilizar C# CodeDom CodeProvider .
Aquí hay una lista de los enfoques más populares que conozco para evaluar expresiones de cadena dinámicamente en C#.
Soluciones Microsoft
- Proveedor de código C# CodeDom :
- Vea cómo solía funcionar LINQ y este artículo de CodeProject.
- Roslyn :
- Consulte este artículo sobre Rosly Emit API y esta respuesta de StackOverflow
- Tabla de datos.Compute :
- Vea esta respuesta en StackOverflow
- Navegador web.Documento.InvokeScript
- Vea esta pregunta de StackOverflow
- DataBinder.Eval
- Control de secuencias de comandos
- Vea esta respuesta en StackOverflow y esta pregunta
- Ejecutando PowerShell:
- Vea este artículo de CodeProject
Soluciones que no son de Microsoft (no es que haya nada malo en ello)
- Bibliotecas de evaluación de expresiones:
- Huir
- DinámicoExpresso
- NCalc
- CodificaciónSeb.ExpressionEvaluator
- Evaluación-Expresión.NET
- Intérprete de JavaScript
- Jint
- Para ejecutar C# real
- secuencia de comandos CS
- Haga su propio kit de herramientas para desarrollar el lenguaje como:
- Ironía
- Rompecabezas