简体   繁体   English

像C#的计算引擎这样的东西?

[英]Such a thing as a calculation engine for C#?

Is there any calculation engine for C# that can automatically recalculate dependent fields when a value changes? 是否有任何C#计算引擎可以在值更改时自动重新计算相关字段?

Let me freestyle for a second, I'm imagining something like this.. 让我自由泳一秒钟,我想象这样的事情..

 Field<double> quantity = Field.Create<double>("Quantity");
 Field<double> unitCost = Field.Create<double>("Unit Cost");
 Field<double> total = Field.Create<double>("Total");

 total.Calculation((q,uc) => q * uc, quantity, value);
      // would have signature something like this:
      // void Calculation<TR,T1,T1>(Func<TR,T1,T2>, Field<T1>, Field<T2>)

This would set up fields that auto-propagate dependent values. 这将设置自动传播依赖值的字段。

 quantity.Value = 5.0;
 unitCost.Value = 1.5;
 Assert.That(total.Value, Is.EqualTo(7.5));

Obviously this is a simple example, the end uses would be much more akin to the calculations of a complex spreadsheet. 显然这是一个简单的例子,最终用途更类似于复杂电子表格的计算。

Thinking further it would be amazing if the field/cells would support change notification. 进一步思考,如果字段/单元格支持更改通知,那将是惊人的。

Have you seen http://ncalc.codeplex.com ? 你见过http://ncalc.codeplex.com吗?

It's extensible, fast (eg has its own cache) enables you to provide custom functions and varaibles at run time by handling EvaluateFunction/EvaluateParameter events. 它的可扩展性,快速性(例如,具有自己的缓存)使您能够通过处理EvaluateFunction / EvaluateParameter事件在运行时提供自定义函数和变量。 Example expressions it can parse: 它可以解析的示例表达式:

Expression e = new Expression("Round(Pow(Pi, 2) + Pow([Pi2], 2) + X, 2)");

  e.Parameters["Pi2"] = new Expression("Pi * Pi");
  e.Parameters["X"] = 10;

  e.EvaluateParameter += delegate(string name, ParameterArgs args)
    {
      if (name == "Pi")
      args.Result = 3.14;
    };

  Debug.Assert(117.07 == e.Evaluate());

It also handles unicode & many data type natively. 它还可以本地处理unicode和许多数据类型。 It comes with an antler file if you want to change the grammer. 如果你想改变语法,它会附带一个鹿茸文件。 There is also a fork which supports MEF to load new functions. 还有一个支持MEF加载新功能的fork。

It also supports logical operators, date/time's strings and if statements. 它还支持逻辑运算符,日期/时间的字符串和if语句。

a solution 一个办法

You could possibly do automatic recalculation by implementing INotifyPropertyChanged then doing something like 您可以通过实现INotifyPropertyChanged然后执行类似操作来自动重新计算

  • set a field's expression this.Field.Expression = new Expression("Field1+Field2"); 设置一个字段的表达式this.Field.Expression = new Expression(“Field1 + Field2”);

On notifypropertyupdated in the class 关于课堂上的notifypropertyupdated

  • for each field (with reflection) that is a Function 对于作为函数的每个字段(带反射)
  • if it's expression refers to the changed field then recalculate the variable. 如果它的表达式引用了更改的字段,则重新计算变量。
  • on recalculation you'd need to handle the EvaluateParameter event to use reflection to find the right field and extract its value (you could cache to avoid reflection if needed) 在重新计算时,您需要处理EvaluateParameter事件以使用反射来查找正确的字段并提取其值(如果需要,可以缓存以避免反射)

I would recommend to also give a look at Jace. 我建议你也看看Jace。 Jace is a more modern calculation engine for the .NET framework. Jace是.NET框架的更现代的计算引擎。 It is a lot faster then the above proposed NCalc. 它比上面提出的NCalc快得多。 Furthermore it supports more platforms (.NET, WinRT, WP7 and WP8). 此外,它支持更多平台(.NET,WinRT,WP7和WP8)。

More information about Jace can be found on the GitHub page: https://github.com/pieterderycke/Jace 有关Jace的更多信息,请访问GitHub页面: https//github.com/pieterderycke/Jace

NuGet link: https://www.nuget.org/packages/Jace NuGet链接: https//www.nuget.org/packages/Jace

There are calculation engines for scalar parameters, and there are higher-level calculation engines for tables, typically used for applications like financial planning, fee and commission calculations, network and contract computations... 标量参数有计算引擎,表有更高级别的计算引擎,通常用于财务规划,费用和佣金计算,网络和合同计算等应用程序......

Let me explain this shortly. 让我稍后解释一下。 Consider following formulas for scalars: 考虑以下scalars公式:

1) z = f1(x,y)
2) p = f2(z,n)
3) q = f3(x,p)
...

and so on. 等等。 Configuring such functions and dependency trees requires a calculation engine with scalar parameters. 配置此类函数和依赖关系树需要具有标量参数的计算引擎。 I would (also) recommend following link for such a calculation engine written in c# as a good starting point: http://www.codeproject.com/Articles/246374/A-Calculation-Engine-for-NET 我会(也)推荐以c#编写的这种计算引擎的以下链接作为一个很好的起点: http//www.codeproject.com/Articles/246374/A-Calculation-Engine-for-NET

As mentioned, there are also calculation engines with table functions that take tables as parameters. 如上所述,还有一些带有表函数的计算引擎,它将表作为参数。 The main principle is but the same: 主要原则是相同的:

1) (T4, T5) = TableFunction1(T1, T2, T3)  
2) (T7, T8) = TableFunction2(T2, T4)
...

and so on. 等等。 Note that a table function can return multiple tables as outputs, as shown above. 请注意,表函数可以将多个表作为输出返回,如上所示。

There two key issues to be observed here: 这里有两个关键问题:

a) The values of tables T7 and T8 depend on tables T2 and T4. a)表T7和T8的值取决于表T2和T4。 Therefore, the tables T7 and T8 need to be updated by executing the function "TableFunction2" only if there is a change in one of the input parameters T2 or T4. 因此,只有当输入参数T2或T4之一发生变化时,才需要通过执行函数“TableFunction2”来更新表T7和T8。

Similarly, T4 need to be updated only if T1, T2 or T3 is updated; 同样,只有更新T1,T2或T3时才需要更新T4; dependency tree! 依赖树!

b) Separation of database from the calculation process: The calculation engine must work independent of any fixed data structure or database schema so that it can be integrated with any database and data structure. b)从计算过程中分离数据库:计算引擎必须独立于任何固定数据结构或数据库模式工作,以便它可以与任何数据库和数据结构集成。

You can find my related article where these principles are explained at: 您可以找到我的相关文章,其中解释了这些原则:

Logical Architecture of a Rule-Based Calculation Framework http://finaquant.com/logical-architecture-of-a-rule-based-calculation-framework/1053 基于规则的计算框架的逻辑体系结构http://finaquant.com/logical-architecture-of-a-rule-based-calculation-framework/1053

Now, a C#/.NET library for a calculation engine with tables as input and output parameters is being developed based on these principles. 现在,正在基于这些原理开发用于计算引擎的C#/ .NET库,其中表格作为输入和输出参数。

Note to moderators: Please delete the link above if it is counted as self-promotion. 主持人请注意:如果被视为自我推销,请删除上面的链接。

I asked a similar question here: Truly declarative language? 我在这里问了一个类似的问题: 真正的声明性语言?

As far as I know not, only just heard about NCalc, I'll look into it. 据我所知,只是刚刚听说过NCalc,我会调查一下。 I have a project that does pretty much what you describe and then some like caching/ cache dropping on changes to values or model structure. 我有一个项目几乎完成了你所描述的内容,然后有些项目就像缓存/缓存更改值或模型结构。 Think f it as a crossover between a database and Excel. 认为它是数据库和Excel之间的交叉。 You can also define classes etc and link them together into large models with millions of objects in graphs, not just trees. 您还可以定义类等,并将它们链接到具有图形中数百万个对象的大型模型中,而不仅仅是树。 Client server etc. Also there's a model editor where you create models in a UI so you can analyse how all the calculations build on each other. 客户端服务器等。还有一个模型编辑器,您可以在UI中创建模型,以便分析所有计算在彼此之间的构建方式。

Why exactly are you asking? 你为什么要问?

One of problems with generic rule engine efficiency is recalculation of sums groups etc. Imagine that you want to calculates sum of VAT taxes. 通用规则引擎效率的一个问题是重新计算总和组等。想象一下,您想要计算增值税的总和。 In your invoice event appeared that some product changed and vat changed from one to another. 在您的发票事件中,似乎某些产品发生了变化,并且增值税从一个变为另一个。 Now the simples solution is to recalculate all taxes. 现在简单的解决方案是重新计算所有税收。 But we could imagine smart solution that we know that in given group we need to subtract vat amount and add it to another group. 但我们可以想象智能解决方案我们知道在给定的组中我们需要减去增值税并将其添加到另一个组。 Another problem is cycles. 另一个问题是周期。 We can have demand that our engine would calculate part of remaining to pay amount when we enter it into paid field. 当我们将其输入付费字段时,我们可以要求我们的引擎计算剩余部分的支付金额。 And in another case we would want to calculate paid field if we enter it into remaining to pay field. 在另一种情况下,如果我们将其输入剩余付款字段,我们将要计算付费字段。 This could be done by virtual field "which field was entered by user" and if depending on it in the rule 这可以通过虚拟字段“由用户输入哪个字段”并且如果在规则中依赖于它来完成

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM