2009-05-29 82 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#表达式解析器,您可以在其中传递包含表达式的字符串,并将计算结果返回。