首先,我在.Net方面没有太多经验 - 特别是在过去的7年里.
我正在尝试开发一个应用程序,并将合并另一个库(https://github.com/Giorgi/Math-Expression-Evaluator)
那个库允许我评估数学表达式Evaluate("a+b", a: 1,b: 1).方法签名是public decimal Evaluate(string expression, object argument = null)
我真的只是寻找文档和更多信息的指针..感谢您的任何事情.
编辑:抱歉..故意留下它广泛,因为我不是在寻找人为我做我的工作..似乎无法找到一个起点做我自己的研究.
该方法称为
dynamic engine = new ExpressionEvaluator() ;
engine.Evaluate("(c+b)*a", a: 6, b: 4.5, c: 2.6)) ;
Run Code Online (Sandbox Code Playgroud)
在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;
Run Code Online (Sandbox Code Playgroud)
我希望能够做的是解析像"a:1,b:2"之类的字符串并将其转换为与该Evaluate()签名匹配的对象.
xan*_*tos 11
那个图书馆正在使用高级魔法...非常高级:-)
诀窍是该类声明为:
public class ExpressionEvaluator : DynamicObject
Run Code Online (Sandbox Code Playgroud)
所以它是一个实现dynamic.NET 4.0中引入的魔力的类
现在......在课堂上有两种Evaluate方法:
public decimal Evaluate(string expression, object argument = null)
Run Code Online (Sandbox Code Playgroud)
和
private decimal Evaluate(string expression, Dictionary<string, decimal> arguments)
Run Code Online (Sandbox Code Playgroud)
通常可见和可用的唯一方法是第一种方法.它用作:
engine.Evaluate("a + b + c", new { a = 1, b = 2, c = 3 });
Run Code Online (Sandbox Code Playgroud)
在new { ... }创建一个匿名对象,也就是,然后"解包" 在这里通过使用反射到Dictionary<string, decimal>要被输送到private Evaluate().
如果您尝试使用其他表示法,则表示如下:
engine.Evaluate("a + b + c", a: 1, b: 2, c: 3 });
Run Code Online (Sandbox Code Playgroud)
那么.NET无法将该方法与现有方法相匹配public Evaluate(),但是作为子类的类DynamicObject会导致C#编译器编写一些启动此方法的"魔术"代码(仍然由ExpressionEvaluator实现):
public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
Run Code Online (Sandbox Code Playgroud)
首先检查我们要调用Evaluate:
if (nameof(Evaluate) != binder.Name)
Run Code Online (Sandbox Code Playgroud)
如果我们试图调用Evaluate,它会将参数解压缩到a new Dictionary<string, decimal>()然后调用private Evaluate().
作为旁注,要使用"动态"的写作方式,Evaluate你必须声明engine变量之类的;
dynamic dynamicEngine = new ExpressionEvaluator();
Run Code Online (Sandbox Code Playgroud)
所以使用dynamic变量类型.
现在......在编写库时,您可以:
使用匿名对象,问题是匿名对象必须在编译时定义它们的"形状"(所以在编译时你必须知道你需要a a,a b和a c.d如果你没有,你不能在运行时使用它new { a, b, c, d }在编译时创建一个.例如,请参阅我三年前提供的有关如何在运行时创建动态匿名类型的响应.我为该代码块提供的原因之一是:
.NET框架的某些部分大量使用反射来渲染对象(例如所有各种数据网格).这些部分与动态对象不兼容,通常不支持object [].解决方案通常是将数据封装在DataTable中......或者您可以使用此:-)
请注意,在该响应的一个注释中,有一个链接指向由Dynamic.Linq的众多实现之一使用的我的代码的修改版本.
使用非匿名对象(a new Foo { a = 1, b = 2 c = 3 }).该库不区分匿名和非匿名对象.与以前一样的限制,因为在编译时你需要一个Foo具有正确数量参数的类
使用dynamic符号.可悲的是,即使这是非常静态的.您无法轻松添加新参数,必须在编译时定义"变量"的数量和名称.
一种可能的解决方案是修改源代码(它是单个文件)并制作public此方法:
private decimal Evaluate(string expression, Dictionary<string, decimal> arguments)
Run Code Online (Sandbox Code Playgroud)
然后你可以轻松地动态填充 Dictionary<string, decimal> arguments
| 归档时间: |
|
| 查看次数: |
115 次 |
| 最近记录: |