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

然而,theese对象几乎可以是任何东西,我们无法硬编码如何将测量值聚合到分类中,我们需要将其留给用户。

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

有帮助吗?

解决方案

逃离表达评估器

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

其他提示

您的情况是域特定语言的完美案例。 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的更多信息。

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

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

免责声明:我拥有SpreadsheetGear LLC

我编写了一个开源项目, Dynamic Expresso ,可以转换使用a编写的文本表达式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

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

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

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

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

您对测量执行排他性有多重要?保护用户不要定义重叠状态可能是最难的部分,因为根据您的描述,似乎完全不同的测量对于连接到不同的状态是有效的。

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

很抱歉这么说,但实际上你的问题非常普遍。祝你好运。

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

scroll top