C# 中的用户定义公式

发布于 2024-08-09 06:01:59 字数 234 浏览 3 评论 0原文

我有一个应用程序,用户可以为每个对象指定他自己的测量点。然后,这些测量值将用于将对象分类为:A - 需要服务,B - 服务应在 X 天内安排,C - 不需要 ATM 服务。

但是,这些对象几乎可以是任何对象,我们无法做到这一点硬编码如何将测量值聚合到分类,我们需要将其留给用户。

您对我们如何为用户提供输入自己的公式的方式有什么建议吗?它不一定是防白痴的,我们没有那么多客户,所以只要他们能向我们解释,我们就可以帮助他们。

I have an application where for each object the user can specify his own measurepoints. The values of theese measurements will then be used to classify the object as i e A - needs service, B - service should be scheduled within X days, C - no service needed ATM

However theese objects can be almost anything and there is no way we can hard code how the measured values should be aggregated to a classification, we need to leave that to the user.

Have you any suggestions on how we can provide a way for the user to enter his own formulas for this? It does not have to be idiot-proof, we dont have that many customers so we can assist them as long as they can explain it to us.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

嘿嘿嘿 2024-08-16 06:01:59

我编写了一个开源项目 Dynamic Expresso,它可以将使用 C# 语法编写的文本表达式转换为委托(或表达式树)。表达式被解析并转换为表达式树,而不使用编译或反射。

您可以这样写:

var interpreter = new Interpreter();
var result = interpreter.Eval("8 / 2 + 2");

或者

var interpreter = new Interpreter()
                .SetVariable("service", new ServiceExample());

string expression = "x > 4 ? service.SomeMethod() : service.AnotherMethod()";

Lambda parsedExpression = interpreter.Parse(expression, 
                        new Parameter("x", typeof(int)));

parsedExpression.Invoke(5);

我的工作基于 Scott Gu 文章 http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the- linq-dynamic-query-library.aspx

I have written an open source project, Dynamic Expresso, that can convert text expression written using a C# syntax into delegates (or expression tree). Expressions are parsed and transformed into Expression Trees without using compilation or reflection.

You can write something like:

var interpreter = new Interpreter();
var result = interpreter.Eval("8 / 2 + 2");

or

var interpreter = new Interpreter()
                .SetVariable("service", new ServiceExample());

string expression = "x > 4 ? service.SomeMethod() : service.AnotherMethod()";

Lambda parsedExpression = interpreter.Parse(expression, 
                        new Parameter("x", typeof(int)));

parsedExpression.Invoke(5);

My work is based on Scott Gu article http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx .

栩栩如生 2024-08-16 06:01:59

Flee 表达式评估器

您可以为用户提供有效使用的变量列表,并让他们提出他们自己的表达方式。然后,您将所有表达式、变量名称和值传递给 Flee,它会将所有表达式解析为值或 true/false。

Flee expression evaluator

You could give the users a list of variables that are valid to use and let them come up with their own expressions. You would then pass all the expressions, variable names and values to Flee and it would resolve all expressions to a value or true/false.

反话 2024-08-16 06:01:59

您的情况是特定领域语言的完美案例。 DSL 允许您为“公式语言”指定允许的语法,然后向用户提供反馈并计算结果。

Antlr 是一个非常好的工具。它是一个解析器/lexar 生成器。基本上,您可以在 Antlr 自己的描述 DSL 中指定语法,它会以您选择的语言为您生成强大的词法分析器和解析器。

例如,如果您的语言允许简单的计算,这就是它在 antlr 语言中的指定方式(来自 antlr 的 wiki):

grammar SimpleCalc;

options {
    language=CSharp2;
}

tokens {
    PLUS    = '+' ;
    MINUS   = '-' ;
    MULT    = '*' ;
    DIV = '/' ;
}

@members {
    public static void Main(string[] args) {
        SimpleCalcLexer lex = new SimpleCalcLexer(new ANTLRFileStream(args[0]));
        CommonTokenStream tokens = new CommonTokenStream(lex);

        SimpleCalcParser parser = new SimpleCalcParser(tokens);

        try {
            parser.expr();
        } catch (RecognitionException e)  {
            Console.Error.WriteLine(e.StackTrace);
        }
    }
}

/*------------------------------------------------------------------
 * PARSER RULES
 *------------------------------------------------------------------*/

expr    : term ( ( PLUS | MINUS )  term )* ;

term    : factor ( ( MULT | DIV ) factor )* ;

factor  : NUMBER ;


/*------------------------------------------------------------------
 * LEXER RULES
 *------------------------------------------------------------------*/

NUMBER  : (DIGIT)+ ;

WHITESPACE : ( '\t' | ' ' | '\r' | '\n'| '\u000C' )+    { $channel = HIDDEN; } ;

fragment DIGIT  : '0'..'9' ;

您可以找到有关 DSL 的更多信息 此处

Your situation is a perfect case for a domain specific language. A DSL would allow you to specify an allowable grammar for your "formula language" and then provide feedback to the user as well as calculate the result.

Antlr is a very good tool for this. It is a parser/lexar generator. Basically you specify the grammar in Antlr's own description DSL, and it generates robust lexers and parsers for you in your language of choice.

For example, if your language allows simple calculations this is how it would be specified in antlr's language (from antlr's wiki):

grammar SimpleCalc;

options {
    language=CSharp2;
}

tokens {
    PLUS    = '+' ;
    MINUS   = '-' ;
    MULT    = '*' ;
    DIV = '/' ;
}

@members {
    public static void Main(string[] args) {
        SimpleCalcLexer lex = new SimpleCalcLexer(new ANTLRFileStream(args[0]));
        CommonTokenStream tokens = new CommonTokenStream(lex);

        SimpleCalcParser parser = new SimpleCalcParser(tokens);

        try {
            parser.expr();
        } catch (RecognitionException e)  {
            Console.Error.WriteLine(e.StackTrace);
        }
    }
}

/*------------------------------------------------------------------
 * PARSER RULES
 *------------------------------------------------------------------*/

expr    : term ( ( PLUS | MINUS )  term )* ;

term    : factor ( ( MULT | DIV ) factor )* ;

factor  : NUMBER ;


/*------------------------------------------------------------------
 * LEXER RULES
 *------------------------------------------------------------------*/

NUMBER  : (DIGIT)+ ;

WHITESPACE : ( '\t' | ' ' | '\r' | '\n'| '\u000C' )+    { $channel = HIDDEN; } ;

fragment DIGIT  : '0'..'9' ;

You can find out more about DSLs in general here.

人生百味 2024-08-16 06:01:59

SpreadsheetGear for .NET 可能是一个不错的选择。 SpreadsheetGear 接受并计算大多数用户已知语言(Excel)中的公式。 SpreadsheetGear 包含一个 Windows 窗体电子表格控件,或者如果您正在使用 ASP.NET 或 Web 服务,则可以将其用作库。

您可以在此处查看简单的 ASP.NET 计算示例,或下载免费试用版如果您想尝试 WinForms 控件,请点击此处

免责声明:我拥有 SpreadsheetGear LLC

SpreadsheetGear for .NET might be a good choice. SpreadsheetGear accepts and calculates formulas in the language most users already know - Excel. SpreadsheetGear includes a Windows Forms spreadsheet control, or you can use it as a library if you are doing ASP.NET or a web service.

You can see simple ASP.NET calculation samples here, or download the free trial here if you want to try the WinForms control.

Disclaimer: I own SpreadsheetGear LLC

×纯※雪 2024-08-16 06:01:59

您应该在 System.Linq.Expressions 中使用 .NET 3.5 表达式。 Scott Gu 提供了一个动态表达式 API,允许您计算字符串以将其转换为表达式树,然后可以通过代码计算表达式树以检查表达式内容,或编译执行。

http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx

You should use .NET 3.5 Expressions, in System.Linq.Expressions. Scott Gu has provided a Dynamic Expression API that allows you to evaluate strings to turn them into expression trees, which may then be evaluated by code either to examine the expression contents, or compiled for execution.

http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx

浮云落日 2024-08-16 06:01:59

您提到这些对象可以是“几乎任何东西”。测量点可以是几乎任何东西吗?据推测,测量将仅限于所讨论对象的已定义属性,在这种情况下,您可能会公开一个类似向导的编辑器,该编辑器将允许用户根据通过反射发现的对象属性执行计算。通过限制问题,您可以做的一件事是您似乎强制执行 3 个端点进行测量,而不是 1 到 N 个状态。

最后一个建议,我认为为了获得足够的灵活性,您将需要一个独立的测量对象模型来绑定到您想要测量的对象。

对您来说,强制实施测量的排他性有多重要?保护用户不定义重叠状态可能是其中最困难的部分,因为从您的描述来看,完全不同的测量似乎可以有效地附加到不同的状态。

另外,您知道如何轮询对象以计算测量值来定义对象的状态吗?

很抱歉这么笼统地说,但实际上您的问题在这一点上非常笼统。祝你好运。

You mention the objects can be "almost anything". Can the measure points also be almost anything? Presumably the measurements would be limited to defined properties of the object in question, in which case you could presumably expose a wizard-like editor that would allow the user to perform calculations based on object properties discovered via reflection. One thing you have going for you by way of bounding the problem is you seem to be enforcing 3 endpoints for measurement instead of 1 to N states.

One last suggestion, I think for sufficient flexibility you will need an independent measurement object model that binds to the objects you wish to measure.

How important is it for you to enforce exclusivity on the measurements? Protecting the user from defining overlapping states will perhaps be the toughest piece of this, since from your description it would seem that entirely different measurements are valid to attach to different states.

Also, do you know how you will be polling the objects to calculate measurements to define the state of the objects?

Sorry to speak so generally but really at this point your question is pretty general. Good luck.

诗笺 2024-08-16 06:01:59

用户能否利用他对对象的了解,在将其输入系统时决定将其放入哪个类别?我猜我们需要更多信息,但如果用户可以定义哪些测量点决定哪个类别,他们难道不能只选择类别吗?

Could the user use his knowledge of the object and just decide which category to put it in when he enters it into the system? Guess we need more info but if the user can define which measurepoints determine which category, couldn't they just choose the category?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文