Proč by to nezkouslo výrazy typu a < b < c? Generátor C# třídy lze například upravit, že dostane libovolný počet parametrů, ze kterých potom udělá property a mohu je ve vyhodnocovaném výrazu použít. S výkonovou a paměťovou náročností máte pravdu, ale netuším v jaké aplikaci to chce tazatel použít. Nicméně je určitě dobré na to upozornit a udělat nějaký jednoduchý zátěžový test. V komentářích pod článkem je zmíněné ještě jedno řešení, které je výkonově mnohem lepší, protož využívá JScriptovou funkci Eval. V tomto případě se v paměti zkompiluje pouze jedna assembly a ta se potom opakovaně používá.
using System;
using System.CodeDom.Compiler;
using System.Reflection;
using Microsoft.JScript;
namespace Expressions
{
public class JScriptEvaluator
{
public static int EvalToInteger(string statement)
{
string s = EvalToString(statement);
return int.Parse(s.ToString());
}
public static string EvalToString(string statement)
{
object o = EvalToObject(statement);
return o.ToString();
}
public static object EvalToObject(string statement)
{
return _evaluatorType.InvokeMember(
"Eval",
BindingFlags.InvokeMethod,
null,
_evaluator,
new object[] { statement }
);
}
static JScriptEvaluator()
{
CodeDomProvider provider = new Microsoft.JScript.JScriptCodeProvider();
CompilerParameters parameters = new CompilerParameters();
parameters.GenerateInMemory = true;
CompilerResults results = provider.CompileAssemblyFromSource(parameters, _jscriptSource);
Assembly assembly = results.CompiledAssembly;
_evaluatorType = assembly.GetType("Evaluator.Evaluator");
_evaluator = Activator.CreateInstance(_evaluatorType);
}
private static object _evaluator = null;
private static Type _evaluatorType = null;
private static readonly string _jscriptSource =
@"package Evaluator
{
class Evaluator
{
public function Eval(expr : String) : String
{
return eval(expr);
}
}
}";
}
}
|