我有一个应用程序,其中对于每个对象用户可以指定他自己的测量点。这些测量值将被用于将对象分类为:A - 需要服务,B - 服务应该在X天内安排,C - 不需要服务ATM用户在C#中定义的公式#
然而,这些对象几乎可以是任何东西,我们无法硬编码如何将测量值汇总到分类中,因此我们需要将其留给用户。
对于我们如何为用户输入自己的公式提供方法,您有什么建议吗?它不一定是傻瓜证明,我们没有那么多的客户,所以我们可以帮助他们,只要他们能向我们解释。
我有一个应用程序,其中对于每个对象用户可以指定他自己的测量点。这些测量值将被用于将对象分类为:A - 需要服务,B - 服务应该在X天内安排,C - 不需要服务ATM用户在C#中定义的公式#
然而,这些对象几乎可以是任何东西,我们无法硬编码如何将测量值汇总到分类中,因此我们需要将其留给用户。
对于我们如何为用户输入自己的公式提供方法,您有什么建议吗?它不一定是傻瓜证明,我们没有那么多的客户,所以我们可以帮助他们,只要他们能向我们解释。
你可以给用户的是有效的使用,让他们拿出自己的表情变量列表。然后,您会将所有表达式,变量名称和值传递给Flee,并将所有表达式解析为值或真/假。
您应该在System.Linq.Expressions中使用.NET 3.5表达式。 Scott Gu提供了一个Dynamic Expression API,允许您评估字符串以将它们转化为表达式树,然后可以通过代码来评估它们,以检查表达式内容或编译执行。
你提到的对象可以是 “几乎所有的东西”。衡量点也可以是几乎任何东西?据推测,测量将限于所讨论对象的定义属性,在这种情况下,您可能会公开一个类似向导的编辑器,该编辑器允许用户根据通过反射发现的对象属性执行计算。你通过限制问题的方式为你提供的一件事情是,你似乎正在执行3个端点来进行测量,而不是1到N个状态。
最后一个建议,我认为要有足够的灵活性,您需要一个独立的测量对象模型,它绑定到您想要测量的对象。
它对您对测量执行排他性有多重要?保护用户免于定义重叠状态可能是最难的一件事,因为从您的描述来看,完全不同的测量结果似乎适用于不同的状态。
另外,你知道你将如何轮询对象来计算度量来定义对象的状态吗?
对不起,这么说一般,但真的在这一点上,你的问题是相当普遍的。祝你好运。
我必须在我的问题中更加具体:)你已经给了医药一些想法,但我想我已经在Flee中找到了我的解决方案。 – Freddy 2009-10-29 15:52:13
您的情况是特定领域语言的完美案例。 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一般here。
很好的建议,但我认为Flee提供了所有我需要的代码,而不是比这更少的代码行。 – Freddy 2009-10-29 15:49:23
用户是否可以使用自己对该对象的知识,并决定将其输入系统时将其放入哪个类别?猜猜我们需要更多的信息,但如果用户可以定义哪些测量点确定哪个类别,他们不能只是选择类别?
可能是一个不错的选择。 SpreadsheetGear接受并计算大多数用户已知的语言公式 - Excel。 SpreadsheetGear包含Windows Forms电子表格控件,或者如果您正在执行ASP.NET或Web服务,则可以将其用作库。
如果您想尝试WinForms控件,可以看到简单的ASP.NET计算示例here,或下载免费试用here。
声明:我自己的SpreadsheetGear LLC
尽管我发布了一个关于DSL的ansewer,但我完全赞同并使用Joe的Spreadsheet设备。这是一个很棒的产品。 – 2009-10-29 15:20:33
这可能是我的选择,如果要创建公式的用户不是一个具有良好编程技能的人,然而在这一点上,我不能看到一种情况,我们会让真正的最终用户配置这个更复杂(和免费)解决方案不是问题。但该产品看起来不错,我会牢记未来的产品。 – Freddy 2009-10-29 15:57:15
我写了一个开源项目,Dynamic Expresso,可转换使用C#语法为代表(或表达式树)的书面文字表达。表达式被解析并转换成Expression Trees而不使用编译或反射。
您可以编写类似:
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);
我的工作是基于斯科特谷的文章http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx。
你能解释一下这个问题吗? – BobbyShaftoe 2009-10-29 14:34:20
这可以通过让用户定义将标记对象为1,2或3类的值限制来实现吗?或者对象完全不同? – 2009-10-29 14:53:59
没有,不会这样做。我需要支持最常见的数学函数,最好还有条件运算符。 – Freddy 2009-10-29 16:03:04