我有一個應用程序,其中對於每個對象用戶可以指定他自己的測量點。這些測量值將被用於將對象分類爲: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