2009-05-29 19 views
12

Có thể chuyển đổi chuỗi ký tự thành toán tử để sử dụng trong điều kiện logic không.C# chuyển đổi một chuỗi để sử dụng trong điều kiện logic

Ví dụ

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

hoặc

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

Tôi đánh giá cao điều này có thể không được chuẩn câu hỏi thực tế, do đó tôi không quan tâm đến câu trả lời mà hỏi tôi tại sao các địa ngục muốn làm một cái gì đó như thế này.

Cảm ơn trước

EDIT: OK Tôi đồng ý, chỉ công bằng khi đưa ra một số ngữ cảnh.

Chúng tôi có hệ thống được xây dựng xung quanh sự phản chiếu và XML. Tôi muốn có thể nói một cái gì đó như thế, một cách dễ dàng.

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

EDIT: Cảm ơn nhận xét của bạn, tôi không thể giải thích chính xác điều này tại đây. Tôi đoán câu hỏi của tôi được trả lời bởi "Bạn không thể", đó là hoàn toàn tốt (và những gì tôi nghĩ). Cảm ơn ý kiến ​​của bạn.

EDIT: Sod nó tôi sẽ có một đi.

Hãy tưởng tượng sau

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

này sẽ được phản ánh vào một lớp học, vì vậy bây giờ tôi muốn kiểm tra điều kiện, bằng cách gọi

bool LogicRule.Test() 

Đó là chút nơi mọi thứ rồi cũng cần phải tìm ra cùng với nhau.

EDIT:

OK, vì vậy đã không bao giờ nhìn Lambdas hoặc Expressions Tôi nghĩ tôi sẽ có một cái nhìn sau khi lời đề nghị @ jrista của.

Hệ thống của tôi cho phép Enums được phân tích cú pháp, vì vậy Biểu thức là hấp dẫn vì ExpressionType Enum.

Vì vậy, tôi đã tạo ra lớp sau để thử nghiệm ý tưởng:

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)); 

     } 
    } 

Rõ ràng điều này sẽ chỉ làm việc cho Int32 ngay bây giờ và ExpressionTypes cơ bản, tôi không chắc là tôi có thể làm cho nó chung chung? Tôi chưa bao giờ sử dụng Expressions trước đây, tuy nhiên điều này dường như làm việc.

Bằng cách này sau đó có thể được khai báo theo cách của chúng tôi như XML

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

Tôi sẽ không trả lời "tại sao bạn lại làm điều này" nhưng thay vào đó tôi sẽ bình luận :). Không cố gắng để được một nỗi đau, tôi chỉ tò mò là tại sao điều này là quan trọng đối với ứng dụng của bạn. – JaredPar

+1

@JaredPar: Tôi thấy điều này mọi lúc: mọi người muốn lưu trữ nó trong một db và truy xuất nó để sử dụng trong mã sau. Không có nghĩa đó là một ý tưởng hay, nhưng đó là nơi nó xuất phát. –

+0

Cảm ơn bạn đã cập nhật, nhưng bạn muốn làm gì với XML đó, và nó có ý nghĩa gì? Bạn có muốn có ví dụ đó trong một phần tử, "q" và làm "if (So sánh (q, x))" để so sánh biến "x" theo điều kiện được biểu thị trong phần tử XML không? –

Trả lời

11

Bạn có thể làm một cái gì đó như thế này:

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

Không, nó không thể, và tại sao các địa ngục bạn sẽ wnat để làm điều này?

Bạn có thể, tất nhiên, tạo ra một chức năng như:

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

"op" có thể cần nhiều hơn một char; bạn có thể có "! =" hoặc "<>" hoặc "==" làm toán tử tiềm năng. –

5

EDIT

Như JaredPar chỉ ra, đề nghị của tôi dưới đây sẽ không làm việc như bạn không thể áp dụng các nhà khai thác để generics ...

Vì vậy, bạn cần phải triển khai cụ thể cho từng loại bạn muốn so sánh/tính toán ...

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(); 
    } 
} 

Orig

Bạn có thể làm một cái gì đó như thế này.

Bạn cũng sẽ cần phải thử/nắm bắt tất cả điều này để đảm bảo rằng bất kỳ T là gì, hỗ trợ các hoạt động cụ thể.

Hãy nhớ nếu tôi hỏi tại sao bạn có thể cần phải thực hiện việc này. Bạn đang viết một số loại phân tích cú pháp toán học?

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

Điều đó sẽ biên dịch? Tôi không nghĩ vậy. –

+0

Đây là một cách tiếp cận rất hạn chế mặc dù. Bên ngoài == và! = Bạn không thể sử dụng toán tử trên các giá trị chung. – JaredPar

+0

@ John, có thể không, tôi viết trực tiếp nó vào cửa sổ SO vì vậy nó bán giả @Jared. Có thật không ? ok ... đầu mà ý tưởng ... :( –

0
<Function = "PredicateMore" Param1 = "Object1.Value" Param2 = "0"/> 
0

Tôi nghĩ rằng bạn có thể đạt được một cách chính xác này sử dụng implicit casting. Một cái gì đó như:

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

tôi đã thực hiện một cái gì đó tương tự như sau với sự giúp đỡ của:

http://flee.codeplex.com/

Công cụ này về cơ bản có thể evaulate một loạt các biểu thức. Sử dụng cơ bản sẽ là để vượt qua trong một chuỗi như '3> 4' và công cụ sẽ trả về false.

Tuy nhiên, bạn cũng có thể tạo một thể hiện của bộ đánh giá và chuyển vào cặp tên/giá trị đối tượng và nó có thể trực quan hơn một chút trên IE: myObject^7 < yourObject.

Có rất nhiều chức năng khác mà bạn có thể đi sâu vào trang web codeplex.

3

Bạn nên xem xét sử dụng cây biểu thức .NET 3.5. Bạn có thể xây dựng các biểu thức theo cách thủ công vào một cây biểu thức (về cơ bản là một AST), và sau đó gọi Expression.Compile() để tạo một đại biểu có thể gọi. Phương thức LogicRule.Test() của bạn sẽ cần phải xây dựng cây Expression, bọc cây trong LambdaExpression lấy đối tượng mà bạn áp dụng các quy tắc cũng như một đối số, gọi là Compile(), và gọi đại biểu kết quả.

0

Vici Parser (mã nguồn mở) có thể giúp bạn. Đó là trình phân tích cú pháp biểu thức C#, nơi bạn có thể truyền một chuỗi có chứa một biểu thức và bạn nhận được kết quả tính toán.

Các vấn đề liên quan