C# 转换字符串以用于逻辑条件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/925886/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 03:22:34  来源:igfitidea点击:

C# convert a string for use in a logical condition

c#logic

提问by MrEdmundo

Is it possible to convert a string to an operator for use in a logical condition.

是否可以将字符串转换为运算符以用于逻辑条件。

For example

例如

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

or

或者

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

I appreciate that this might not be standard practice question, therefore I'm not interested in answers that ask me why the hell would want to do something like this.

我很欣赏这可能不是标准的练习问题,因此我对问我为什么他妈的想要做这样的事情的答案不感兴趣。

Thanks in advance

提前致谢

EDIT: OK I agree, only fair to give some context.

编辑:好的,我同意,只是提供一些上下文是公平的。

We have system built around reflection and XML. I would like to be able to say something like, for ease.

我们有围绕反射和 XML 构建的系统。为了方便起见,我希望能够说一些类似的话。

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

EDIT: Thanks for your comments, I can't properly explain this on here. I guess my question is answered by "You can't", which is absolutely fine (and what I thought). Thanks for your comments.

编辑:感谢您的评论,我无法在这里正确解释这一点。我想我的问题是“你不能”回答的,这绝对没问题(也是我的想法)。感谢您的意见。

EDIT: Sod it I'm going to have a go.

编辑:我要去试一试。

Imagine the following

想象以下

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

This will get reflected into a class, so now I want to test the condition, by calling

这将反映到一个类中,所以现在我想通过调用来测试条件

bool LogicRule.Test()

That's the bit where it would all need to come together.

这就是所有需要结合在一起的地方。

EDIT:

编辑:

OK, so having never looked at Lambdas or Expressions I thought I would have a look after @jrista's suggestions.

好的,所以从来没有看过 Lambda 或表达式,我想我会看看@jrista 的建议。

My system allows Enums to be parsed, so Expressions are attractive because of the ExpressionType Enum.

我的系统允许解析枚举,因此由于 ExpressionType 枚举,表达式很有吸引力。

So I created the following class to test the idea:

所以我创建了以下类来测试这个想法:

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

        }
    }

Obviously this will only work for Int32 right now and the basic ExpressionTypes, I'm not sure I can make it generic? I've never use Expressions before, however this seems to work.

显然这现在只适用于 Int32 和基本的 ExpressionTypes,我不确定我能不能让它通用?我以前从未使用过表达式,但这似乎有效。

This way can then be declared in our XML way as

然后可以在我们的 XML 方式中将这种方式声明为

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

采纳答案by Sean

You could do something like this:

你可以这样做:

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

回答by John Saunders

No, it's not possible, and why the hell would you wnat to do this?

不,这是不可能的,你为什么要这样做?

You could, of course, create a function like:

当然,您可以创建一个函数,例如:

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

回答by Eoin Campbell

EDIT

编辑

As JaredPar pointed out, my suggestion below won't work as you can't apply the operators to generics...

正如 JaredPar 指出的那样,我下面的建议不起作用,因为您不能将运算符应用于泛型......

So you'd need to have specific implementations for each types you wanted to compare/compute...

所以你需要为你想要比较/计算的每种类型都有特定的实现......

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

原点

You could do something like this.

你可以做这样的事情。

You'd also need to try/catch all this to ensure that whatever T is, supports the particular operations.

您还需要尝试/捕获所有这些以确保无论 T 是什么,都支持特定的操作。

Mind if I ask why you would possibly need to do this. Are you writing some sort of mathematical parser ?

介意我问你为什么可能需要这样做。你在写某种数学解析器吗?

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

回答by ima

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

回答by James Schek

I think you can achieve exactly this using implicit casting. Something like:

我认为您可以使用隐式强制转换来实现这一点。就像是:

   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.

回答by Bryan Rowe

I've done something similar to this with the help of:

我在以下人员的帮助下做了类似的事情:

http://flee.codeplex.com/

http://flee.codeplex.com/

This tool can essentially evaulate a wide range of expressions. Basic usage would be to pass in a string like '3 > 4' and the tool would return false.

该工具基本上可以评估范围广泛的表达式。基本用法是传入像“3 > 4”这样的字符串,该工具将返回 false。

However, you can also create an instance of the evaluator and pass in object name/value pairs and it can be a little more intuitive IE: myObject^7 < yourObject.

但是,您也可以创建评估器的实例并传入对象名称/值对,它可以更直观一些 IE:myObject^7 < yourObject。

There is a ton more functionality that you can dive into at the codeplex site.

您可以在 codeplex 站点上深入了解更多功能。

回答by jrista

You should look into using .NET 3.5's Expression trees. You can build expressions manually into an expression tree (basically an AST), and then call Expression.Compile() to create a callable delegate. Your LogicRule.Test() method would need to build the Expression tree, wrap the tree in a LambdaExpression that takes the object your applying the rules too as an argument, calls Compile(), and invokes the resulting delegate.

您应该考虑使用 .NET 3.5 的表达式树。您可以手动将表达式构建到表达式树(基本上是一个 AST)中,然后调用 Expression.Compile() 来创建一个可调用的委托。您的 LogicRule.Test() 方法需要构建 Expression 树,将树包装在 LambdaExpression 中,该 LambdaExpression 将您也应用规则的对象作为参数,调用 Compile(),并调用生成的委托。

回答by Philippe Leybaert

Vici Parser(open-source) may be of help to you. It's a C# expression parser where you can just pass a string containing an expression, and you get the computed result back.

Vici Parser(开源)可能对您有所帮助。它是一个 C# 表达式解析器,您可以在其中传递包含表达式的字符串,然后返回计算结果。