Domanda

E 'possibile convertire una stringa in un operatore per l'uso in una condizione logica.

Ad esempio

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

o

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

Mi rendo conto che questo potrebbe non essere questione pratica standard, perciò io non sono interessato a risposte che mi chiedono perché l'inferno vorrebbe fare qualcosa di simile.

Grazie in anticipo

EDIT:. OK Sono d'accordo, giusto per dare qualche contesto

Abbiamo sistema costruito intorno riflessione e XML. Vorrei essere in grado di dire qualcosa di simile, per la facilità.

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

EDIT: Grazie per i vostri commenti, non riesco a spiegare correttamente questo qui. Credo che la mia domanda si risponde con "Non è possibile", che è assolutamente bene (e quello che ho pensato). Grazie per i vostri commenti.

EDIT: SOD che ho intenzione di avere un andare

.

Immaginate la seguente

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

In questo modo vengono riflessi in una classe, in modo da ora voglio testare la condizione, chiamando

bool LogicRule.Test()

Questo è il pezzo in cui tutto sarebbe bisogno di venire insieme.

EDIT:

OK, quindi non avendo mai guardato Lambda Expressions o ho pensato di dare un'occhiata dopo @ di jrista suggerimenti.

Il mio sistema permette Enums da analizzare, in modo da espressioni sono attraenti a causa del ExpressionType Enum.

Così ho creato la seguente classe di testare l'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));

        }
    }

Ovviamente questo funziona solo per Int32 in questo momento e le ExpressionTypes di base, non sono sicuro che posso farlo generica? Non ho mai utilizzare espressioni prima, tuttavia questo sembra funzionare.

In questo modo può quindi essere dichiarato nel nostro modo XML come

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

Soluzione

Si potrebbe fare qualcosa di simile:

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

Altri suggerimenti

Modifica

Come JaredPar ha sottolineato, il mio suggerimento di seguito non funzionerà come non è possibile applicare agli operatori di farmaci generici ...

Così avresti bisogno di avere implementazioni specifiche per ogni tipo si voleva confrontare / 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

Si potrebbe fare qualcosa di simile.

Si sarebbe anche bisogno di try / catch tutto questo per garantire che tutto ciò che è T, supporta le operazioni particolari.

Ti dispiace se mi chiedo perché si sarebbe forse bisogno di fare questo. Stai scrivendo una sorta di parser matematica?

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

No, non è possibile, e perché il diavolo si vuole fare questo?

Si potrebbe, naturalmente, creare una funzione del tipo:

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

Si dovrebbe considerare di usare alberi Espressione .NET 3.5 di. È possibile creare espressioni manualmente in un albero di espressione (in pratica un AST), e quindi chiamare Expression.Compile () per creare un delegato callable. Il tuo metodo LogicRule.Test () avrebbe bisogno di costruire l'albero di espressione, avvolgere l'albero in un LambdaExpression che prende l'oggetto vostra applicazione delle regole anche come argomento, chiama Compile (), e richiama il delegato risultante.

Ho fatto qualcosa di simile a questo con l'aiuto di:

http://flee.codeplex.com/

Questo strumento può essenzialmente evaulate una vasta gamma di espressioni. Utilizzo base sarebbe quella di passare una stringa come '3> 4' e lo strumento sarebbe return false.

Tuttavia, è anche possibile creare un'istanza del valutatore e passa in oggetto coppie nome / valore e può essere un po 'più intuitivo IE:. MyObject ^ 7

C'è una tonnellata più funzionalità che è possibile immergersi in presso il sito CodePlex.

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

Penso che si può ottenere esattamente ciò utilizzando implicita . Qualcosa di simile:

   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.

Vici Parser (open-source) può essere di aiuto a voi. Si tratta di un C # parser espressione in cui si può semplicemente passare una stringa che contiene un'espressione, e si ottiene il risultato calcolato di nuovo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top