我正在尝试开发一个应用程序,并将合并另一个库(https://github.com/Giorgi/Math-Expression-Evaluator)
该库允许我评估数学表达式,如Evaluate(“a b”,a:1,b:1).方法签名是公共十进制Evaluate(字符串表达式,对象参数= null)
>我想更好地了解.Net如何将逗号分隔的参数转换为单个“参数”.
>我不确定如何动态创建该参数…例如,迭代值列表并创建一个与该签名的相应参数匹配的对象.
我真的只是寻找文档和更多信息的指针..感谢您的任何事情.
编辑:抱歉..故意留下它广泛,因为我不是在寻找人为我做我的工作..似乎无法找到一个起点做我自己的研究.
该方法称为
dynamic engine = new ExpressionEvaluator() ; engine.Evaluate("(c+b)*a",a: 6,b: 4.5,c: 2.6)) ;
在Evalute()的主体中是这个代码(它将该参数转换为字符串字典,十进制对.
if (argument == null) { return new Dictionary<string,decimal>(); } var argumentType = argument.GetType(); var properties = argumentType.GetProperties(BindingFlags.Instance | BindingFlags.Public) .Where(p => p.CanRead && IsNumeric(p.PropertyType)); var arguments = properties.ToDictionary(property => property.Name,property => Convert.ToDecimal(property.GetValue(argument,null))); return arguments;
我希望能够做的是解析像“a:1,b:2”之类的字符串,并将其转换为与Evaluate()签名匹配的对象.
解决方法
诀窍是该类声明为:
public class ExpressionEvaluator : DynamicObject
所以它是一个实现.NET 4.0中引入的动态魔法的类
现在……在课堂上有两种评估方法:
public decimal Evaluate(string expression,object argument = null)
和
private decimal Evaluate(string expression,Dictionary<string,decimal> arguments)
engine.Evaluate("a + b + c",new { a = 1,b = 2,c = 3 });
新的{…}创建一个匿名对象,然后通过使用反射到字典< string,decimal>来“解包”here.被送到私人Evaluate().
如果您尝试使用其他表示法,则表示如下:
engine.Evaluate("a + b + c",a: 1,b: 2,c: 3 });
那么.NET无法将该方法与现有的公共Evaluate()相匹配,但是作为DynamicObject的子类的类会导致C#编译器编写一些启动this方法的“魔术”代码(仍然实现)通过ExpressionEvaluator):
public override bool TryInvokeMember(InvokeMemberBinder binder,object[] args,out object result)
首先检查我们要调用Evaluate:
if (nameof(Evaluate) != binder.Name)
如果我们试图调用Evaluate,它会将参数解包为新的Dictionary< string,decimal>(),然后调用私有的Evaluate().
作为旁注,要使用“动态”编写评估方式,你必须声明引擎变量;
dynamic dynamicEngine = new ExpressionEvaluator();
所以使用动态变量类型.
现在……在编写库时,您可以:
>使用匿名对象,问题是匿名对象必须在编译时定义其“形状”(因此在编译时你必须知道你需要aa,ab和c.如果在运行时你不需要广告,如果你没有在编译时创建一个新的{a,b,c,d}.例如,参见我在三年前提供的关于如何在运行时创建动态匿名类型的response.我为该代码块提供的原因之一是:
there are parts of the .NET framework that heavily use reflection to render objects (for example all the varIoUs datagrids). These parts are incompatible with dynamic objects and often don’t support object[]. A solution is often to encapsulate the data in a DataTable… or you can use this 原文链接:https://www.f2er.com/csharp/244320.html