2

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

然而这些对象几乎可以是任何东西,我们无法硬编码应该如何将测量值聚合到一个分类中,我们需要把它留给用户。

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

4

7 回答 7

2

我编写了一个开源项目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

于 2013-02-03T09:23:46.660 回答
1

Flee 表达式评估器

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

于 2009-10-29T14:49:24.090 回答
1

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

Antlr是一个非常好的工具。它是一个解析器/词法分析器生成器。基本上,您在 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 的更多信息。

于 2009-10-29T15:01:16.640 回答
1

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

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

免责声明:我拥有 SpreadsheetGear LLC

于 2009-10-29T15:09:11.997 回答
0

您应该在 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

于 2009-10-29T14:52:26.587 回答
0

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

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

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

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

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

于 2009-10-29T15:00:30.157 回答
0

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

于 2009-10-29T15:07:47.733 回答