- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
首先,我在 .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)) ;
在 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
所以它是一个实现 dynamic
的类.NET 4.0 中引入的魔法
现在...类(class)里有两个Evaluate
方法:
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 });
new { ... }
创建一个匿名对象,然后“解压”here通过对 Dictionary<string, decimal>
的反射使用被喂给private Evaluate()
.
如果您尝试使用其他表示法,例如:
engine.Evaluate("a + b + c", a: 1, b: 2, c: 3 });
然后 .NET 无法将方法与 public Evaluate()
匹配存在,但是该类是 DynamicObject
的子类, 导致 C# 编译器编写一些启动 this 的“魔法”代码方法(仍然由 ExpressionEvaluator 实现):
public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
首先检查我们要调用 Evaluate:
if (nameof(Evaluate) != binder.Name)
如果我们尝试调用 Evaluate,它会将参数解压为 new Dictionary<string, decimal>()
然后调用 private Evaluate()
.
作为旁注,使用“动态”写作方式Evaluate
你必须声明 engine
变量喜欢;
dynamic dynamicEngine = new ExpressionEvaluator();
所以使用 dynamic
变量类型。
现在...随着库的编写,您可以:
使用匿名对象,问题是匿名对象必须在编译时定义它们的“形状”(所以在编译时你必须知道你将需要一个 a
,一个 b
和一个c
。如果您在编译时没有创建 d
,则在运行时不需要 new { 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 :-)
请注意,在对该响应的评论之一中,有一个链接指向我的代码的修改版本,该版本由 Dynamic.Linq 的众多实现之一使用。
使用非匿名对象(new Foo { a = 1, b = 2 c = 3 }
)。该库不区分匿名对象和非匿名对象。和以前一样的限制,因为在编译时你需要一个 Foo
具有正确数量参数的类
使用 dynamic
符号。可悲的是,即使那是相当静态的。您不能轻易添加新参数,因为必须在编译时定义“变量”的数量和名称。
一个可能的解决方案是修改源代码(它是一个文件)并制作public
这个方法:
private decimal Evaluate(string expression, Dictionary<string, decimal> arguments)
然后您可以轻松动态地填充 Dictionary<string, decimal> arguments
关于c# - C#中动态创建数组的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50722680/
我正在尝试创建一个包含 int[][] 项的数组 即 int version0Indexes[][4] = { {1,2,3,4}, {5,6,7,8} }; int version1Indexes[
我有一个整数数组: private int array[]; 如果我还有一个名为 add 的方法,那么以下有什么区别: public void add(int value) { array[va
当您尝试在 JavaScript 中将一个数组添加到另一个数组时,它会将其转换为一个字符串。通常,当以另一种语言执行此操作时,列表会合并。 JavaScript [1, 2] + [3, 4] = "
根据我正在阅读的教程,如果您想创建一个包含 5 列和 3 行的表格来表示这样的数据... 45 4 34 99 56 3 23 99 43 2 1 1 0 43 67 ...它说你可以使用下
我通常使用 python 编写脚本/程序,但最近开始使用 JavaScript 进行编程,并且在使用数组时遇到了一些问题。 在 python 中,当我创建一个数组并使用 for x in y 时,我得
我有一个这样的数组: temp = [ 'data1', ['data1_a','data1_b'], ['data2_a','data2_b','data2_c'] ]; // 我想使用 toStr
rent_property (table name) id fullName propertyName 1 A House Name1 2 B
这个问题在这里已经有了答案: 关闭13年前。 Possible Duplicate: In C arrays why is this true? a[5] == 5[a] array[index] 和
使用 Excel 2013。经过多年的寻找和适应,我的第一篇文章。 我正在尝试将当前 App 用户(即“John Smith”)与他的电子邮件地址“jsmith@work.com”进行匹配。 使用两个
当仅在一个边距上操作时,apply 似乎不会重新组装 3D 数组。考虑: arr 1),但对我来说仍然很奇怪,如果一个函数返回一个具有尺寸的对象,那么它们基本上会被忽略。 最佳答案 这是一个不太理
我有一个包含 GPS 坐标的 MySQL 数据库。这是我检索坐标的部分 PHP 代码; $sql = "SELECT lat, lon FROM gps_data"; $stmt=$db->query
我需要找到一种方法来执行这个操作,我有一个形状数组 [批量大小, 150, 1] 代表 batch_size 整数序列,每个序列有 150 个元素长,但在每个序列中都有很多添加的零,以使所有序列具有相
我必须通过 url 中的 json 获取文本。 层次结构如下: 对象>数组>对象>数组>对象。 我想用这段代码获取文本。但是我收到错误 :org.json.JSONException: No valu
enter code here- (void)viewDidLoad { NSMutableArray *imageViewArray= [[NSMutableArray alloc] init];
知道如何对二维字符串数组执行修剪操作,例如使用 Java 流 API 进行 3x3 并将其收集回相同维度的 3x3 数组? 重点是避免使用显式的 for 循环。 当前的解决方案只是简单地执行一个 fo
已关闭。此问题需要 debugging details 。目前不接受答案。 编辑问题以包含 desired behavior, a specific problem or error, and the
我有来自 ASP.NET Web 服务的以下 XML 输出: 1710 1711 1712 1713
如果我有一个对象todo作为您状态的一部分,并且该对象包含数组列表,则列表内部有对象,在这些对象内部还有另一个数组listItems。如何更新数组 listItems 中 id 为“poi098”的对
我想将最大长度为 8 的 bool 数组打包成一个字节,通过网络发送它,然后将其解压回 bool 数组。已经在这里尝试了一些解决方案,但没有用。我正在使用单声道。 我制作了 BitArray,然后尝试
我们的数据库中有这个字段指示一周中的每一天的真/假标志,如下所示:'1111110' 我需要将此值转换为 boolean 数组。 为此,我编写了以下代码: char[] freqs = weekday
我是一名优秀的程序员,十分优秀!