15

論理条件で使用するために文字列を演算子に変換することは可能ですか?

例えば

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、ラムダや式を見たことがないので、@jrista の提案を見てみたいと思いました。

私のシステムでは Enum を解析できるため、ExpressionType Enum のおかげで Expression は魅力的です。

そこで、アイデアをテストするために次のクラスを作成しました。

    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"/>
4

9 に答える 9

13

次のようなことができます。

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;
 }
}
于 2009-05-29T14:08:50.013 に答える
6

編集

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();
    }
}
于 2009-05-29T13:19:37.743 に答える
4

いいえ、それは不可能です。どうしてそんなことをしたいのですか?

もちろん、次のような関数を作成できます。

 public static bool Compare<T>(char op, T a, T b);
于 2009-05-29T13:16:40.620 に答える
3

.NET 3.5 の式ツリーの使用を検討する必要があります。手動で式を式ツリー (基本的には AST) に構築し、Expression.Compile() を呼び出して呼び出し可能なデリゲートを作成できます。LogicRule.Test() メソッドは Expression ツリーを構築し、ルールを適用するオブジェクトを引数として取り、Compile() を呼び出し、結果のデリゲートを呼び出す LambdaExpression でツリーをラップする必要があります。

于 2009-05-29T16:47:34.740 に答える
2

次の助けを借りて、これと同様のことを行いました。

http://flee.codeplex.com/

このツールは、本質的に幅広い式を評価できます。基本的な使用方法は、'3 > 4' のような文字列を渡すことで、ツールは false を返します。

ただし、エバリュエーターのインスタンスを作成し、オブジェクトの名前と値のペアを渡すこともできます。これは、myObject^7 < yourObject.

codeplex サイトには、さらに多くの機能があります。

于 2009-05-29T16:39:54.890 に答える
0

暗黙のキャストを使用して、これを正確に達成できると思います。何かのようなもの:

   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.
于 2009-05-29T14:52:00.037 に答える
0
<Function = "PredicateMore" Param1 = "Object1.Value" Param2 = "0"/>
于 2009-05-29T13:44:31.060 に答える
0

Vici Parser (オープンソース) が役に立つかもしれません。これは、式を含む文字列を渡すだけで、計算結果が返される C# 式パーサーです。

于 2009-06-01T14:15:10.797 に答える