2009-05-29 77 views
12

是否可以將字符串轉換爲邏輯條件中使用的運算符。C#轉換字符串以便在邏輯條件中使用

例如

if(x Convert.ToOperator(">") y) {} 

if(x ">" as Operator y){} 

我意識到,這可能不是標準的做法問題,所以我不感興趣的答案是問我到底爲什麼要這麼做像這樣的東西。

在此先感謝

編輯:好吧,我同意,公平地給予一定的背景。

我們有圍繞反射和XML構建的系統。我希望能夠輕鬆地說出類似的內容。

<Value = "Object1.Value" Operator = ">" Condition = "0"/> 

編輯:感謝您的意見,我不能在這裏正確解釋這一點。我想我的問題是回答「你不行」,這是絕對好的(以及我的想法)。感謝您的意見。

編輯:點它吧我要去了。

想象一下以下

<Namespace.LogicRule Value= "Object1.Value" Operator=">" Condition="0"> 

這將讓反射到一類,所以現在我要測試的條件下,通過調用

bool LogicRule.Test() 

這就是將所有需要來位一起。

編輯:

OK,所以有從來沒有看過lambda表達式或表達式我想我會@ jrista的建議後,一起來看看。

我的系統允許解析Enums,所以Expression由於ExpressionType Enum而具有吸引力。

所以我創建了下面的類來驗證這一想法:

public class Operation 
    { 
     private object _Right; 
     private object _Left; 
     private ExpressionType _ExpressionType; 
     private string _Type; 

     public object Left 
     { 
      get { return _Left; } 
      set { _Left = value; } 
     } 

     public object Right 
     { 
      get { return _Right; } 
      set { _Right = value; } 
     } 

     public string Type 
     { 
      get { return _Type; } 
      set { _Type = value; } 
     } 

     public ExpressionType ExpressionType 
     { 
      get { return _ExpressionType; } 
      set { _ExpressionType = value; } 
     } 

     public bool Evaluate() 
     { 
      var param = Expression.Parameter(typeof(int), "left"); 
      var param2 = Expression.Parameter(typeof(int), "right"); 

      Expression<Func<int, int, bool>> expression = Expression.Lambda<Func<int, int, bool>>(
       Expression.MakeBinary(ExpressionType, param, param2), param, param2); 

      Func<int, int, bool> del = expression.Compile(); 

      return del(Convert.ToInt32(Left), Convert.ToInt32(Right)); 

     } 
    } 

顯然,這將只對工作的Int32現在的基本ExpressionTypes,我不知道我能做到通用?我從來沒有使用表達式,但是這似乎工作。

這樣,然後可以在我們的XML方式

Operation<Left="1" Right="2" ExpressionType="LessThan" Type="System.Int32"/> 
+0

我不會回答「你爲什麼這樣做」,但我會反而評論它:)。不要試圖成爲一種痛苦,我只是好奇爲什麼這對你的應用程序很重要。 – JaredPar 2009-05-29 13:16:51

+1

@JaredPar:我總是看到這一點:人們希望將它存儲在數據庫中,並在稍後的代碼中檢索它。這並不意味着這是一個好主意,但那是它的來源。 – 2009-05-29 13:18:09

+0

感謝您的更新,但您希望如何處理該XML,這是什麼意思?你是否想在元素「q」中包含該示例,並根據XML元素中表達的條件執行「if(Compare(q,x))」比較變量「x」? – 2009-05-29 13:24:28

回答

11

你可以做這樣的事情:

public static bool Compare<T>(string op, T x, T y) where T:IComparable 
{ 
switch(op) 
{ 
    case "==" : return x.CompareTo(y)==0; 
    case "!=" : return x.CompareTo(y)!=0; 
    case ">" : return x.CompareTo(y)>0; 
    case ">=" : return x.CompareTo(y)>=0; 
    case "<" : return x.CompareTo(y)<0; 
    case "<=" : return x.CompareTo(y)<=0; 
} 
} 
4

不,這是不可能的,憑啥你會wnat做這個聲明?

你可以,當然,創造像一個函數:

public static bool Compare<T>(char op, T a, T b); 
5

編輯

正如JaredPar所指出的,下面我的建議是行不通的,因爲你不能在運營商申請仿製藥......

所以你需要對你想比較/計算每個類型的特定實現...

public int Compute (int param1, int param2, string op) 
{ 
    switch(op) 
    { 
     case "+": return param1 + param2; 
     default: throw new NotImplementedException(); 
    } 
} 

public double Compute (double param1, double param2, string op) 
{ 
    switch(op) 
    { 
     case "+": return param1 + param2; 
     default: throw new NotImplementedException(); 
    } 
} 

你可以做這樣的事情。

您還需要嘗試/捕獲所有這些以確保無論T是什麼,都支持特定的操作。

請記住,如果我問你爲什麼可能需要這樣做。你在編寫某種數學解析器嗎?

public T Compute<T> (T param1, T param2, string op) where T : struct 
{ 
    switch(op) 
    { 
     case "+": 
      return param1 + param2; 
     default: 
      throw new NotImplementedException(); 
    } 
} 

public bool Compare<T> (T param1, T param2, string op) where T : struct 
{ 
    switch (op) 
    { 
     case "==": 
      return param1 == param2; 
     default: 
      throw new NotImplementedException(); 
    } 
} 
0
<Function = "PredicateMore" Param1 = "Object1.Value" Param2 = "0"/> 
0

我想你可以實現正是利用這implicit casting。喜歡的東西:

public static implicit operator Operator(string op) 
    { 
     switch(op) { 
     case "==" : 
      return new EqualOperator(); 
      ... 
     } 
    } 

    Operator op = "<"; 
    if(op.Compare(x,y)) { ... } 
    //or whatever use syntax you want for Operator. 
2

我做了一些與此類似的幫助下:

http://flee.codeplex.com/

這個工具基本上可以evaulate廣泛的表情。基本用法是傳入一個像'3> 4'這樣的字符串,並且該工具將返回false。

但是,您還可以創建評估程序的實例並傳入對象名稱/值對,並且它可以是一個更直觀的IE:myObject^7 < yourObject。

還有更多的功能,您可以在codeplex網站上進行深入研究。

3

你應該看看使用.NET 3.5的表達式樹。您可以將表達式手動構建到表達式樹(基本上是AST)中,然後調用Expression.Compile()來創建可調用委託。您的LogicRule.Test()方法需要構建Expression樹,將樹包裝在一個LambdaExpression中,該LambdaExpression將您應用規則的對象作爲參數,調用Compile()並調用所產生的委託。

0

Vici Parser(開源)可能對您有所幫助。它是一個C#表達式解析器,您可以在其中傳遞包含表達式的字符串,並將計算結果返回。