2010-11-17 53 views
5

我在查找將條件表達式解析爲字符串的方法。將條件表達式解析爲字符串

我能想到的最好的例子是LINQ到SQL。它使用ExpressionVisitors來格式化「Where」子句。例如:

from a in b where a.x == 5 && a.y < 3 select a 

這將轉化爲下面的字符串(大約MSSQL是不是目前對我來說):

"SELECT * FROM b WHERE x = 5 AND y < 3" 

從我讀過,這是使用ExpressionVisitor類來完成,如在這篇文章中解釋:http://blogs.msdn.com/b/mattwar/archive/2007/07/31/linq-building-an-iqueryable-provider-part-ii.aspx

現在的問題是,我不使用LINQ,但我需要這種特殊的功能。有沒有解析這種情況的方法?我願意做任何反思,代表,拉姆達等

老實說,我不認爲這是可能的,但我的大腦有點油炸(閱讀:如果問題是荒謬的很好) ,所以我想我可能也試試S/O。

編輯:最終用途例如:

// Usage: 
foo.Bar(foo => foo.X == 5 && foo.Y < 3) 

// Ideal string output (variable name (foo) is not needed): 
"foo.X == 5 && foo.Y < 3" 

編輯2:是的,一個號可以是小於3和等於5。告訴你,我的大腦是炒。

+0

LINQ到SQL正是這樣做的。如果你自己寫,你會重新實現已經存在的LINQ到SQL,這似乎是一個毫無意義的努力。 (然而,人們已經完成了這項工作,例如谷歌的IQToolkit)。你說過「我不使用LINQ」,但是你的代碼說的是相反的(它充滿了LINQ;表達式樹被認爲是LINQ的一部分)。 – Timwi 2010-11-17 02:15:19

回答

4

如果是關於構建表達式樹本身,那麼您可以利用C#編譯器的能力。

只要Func的類型參數是已知的,就可以將lambda表達式傳遞給函數接受Expression>,這是合法的。例如

private static void PrintExpression(Expression<Func<int, bool>> lambda) 
{ 
     Console.WriteLine(lambda.ToString()); 
} 

可以被稱爲

PrintExpression(a=> a > 0 && a < 5); 

您可以使用泛型即興爲

private static void PrintExpression<T1,T2>(Expression<Func<T1, T2>> lambda) 
{ 
     Console.WriteLine(lambda.ToString()); 
} 

PrintExpression<int, bool>(a=> a > 0 && a < 5); 

調用它表達的自定義打印部分,你可以寫成使用遞歸函數來打印適合您的表達式或任何其他邏輯。

請記住,lambda表達式在編譯時被編譯成一個表達式 - 所以不能用已編譯的Func來替代它。

作爲替代方案,您始終可以構建自定義查詢提供程序,但這會略微偏離目的 - 因爲您需要將其綁定某種可查詢(再次自定義)。

3

嘗試這樣:

static string GetExpressionString<T>(Expression<Func<T, bool>> expression) 
{ 
    return expression.Body.ToString(); 
} 

用法像這樣:

string s = GetExpressionString<Foo>(foo => foo.X == 5 && foo.Y < 3); 

將返回:

((foo.X = 5) && (foo.Y < 3)) 
+0

哦,哇,我發誓我的回答不在這裏,當我貼我的!他有點深入,但我想我會離開我的。 – MatthewKing 2010-11-17 04:12:32

+0

我想補充一點,刪除任何強類型,並允許「對象」會更有用。 :) – Lazlo 2010-12-02 21:01:33

相關問題