2010-05-04 16 views
7

me gustaría hacer lo siguiente:¿Hay una clase .NET que represente tipos de operador?

*OperatorType* o = *OperatorType*.GreaterThan; 

int i = 50; 

int increment = -1; 

int l = 0; 

for(i; i o l; i = i + increment) 
{ 
    //code 
} 

este concepto puede ser kludged en JavaScript utilizando una eval() ... pero esta idea es tener un bucle que puede ir hacia delante o hacia atrás sobre la base de los valores establecido en tiempo de ejecución.

¿Esto es posible?

Gracias

Respuesta

13

Sí, está en .NET Expression trees. En concreto, es necesario utilizar BinaryExpression.Add(). La construcción de árboles de expresión no necesita hacerse a mano, el compilador estará encantado de convertir cualquier expresión lambda que vea asignada a Expression<T> en un árbol de Expresión válido.

// Creating an expression tree. 
Expression<Func<int, int, bool>> greaterThan = (l, r) => l > r; 

int i = 50; 

int increment = -1; 

int l = 0; 

for(i; greaterThan(o, i); i = i + increment) 
{ 
    //code 
} 

Invocando el árbol de expresión compilará automáticamente en un método dinámico y greaterThan actuará eficazmente como un delegado.

+0

¿Cuál es el motivo para usar Expression en lugar de solo delegar simple Func? – fearofawhackplanet

+0

El uso de func simplemente crearía una función anónima vinculada a un delegado. Se construirá en tiempo de compilación. Por otro lado, asignar el lambda a Expression hace que el compilador emita un árbol de expresiones que se puede manipular en tiempo de ejecución. El método anónimo no puede. –

4
Func<int,int,bool> op = (i1, i2) => i1 > i2; 

continuación

op(i, l); 
2

Editar: Agregado uno con función lambda:

Func<int, int, bool> lessThan = (num1, num2) => num1 < num2; 
    Func<int, int, bool> greaterThan = (num1, num2) => num1 > num2; 
    public void Run() 
    { 
     int increment = -1; 
     int l = 0; 
     Func<int, int, bool> c = lessThan; 
     for (int i = 50; c(i, l); i = i + increment) 
     { 

     } 
    } 

estoy seguro que la gente llegar a soluciones mucho más elegante que esto, pero aquí es:

public enum Comparison 
    { 
     GreaterThan, 
     LessThan 
    } 
    public bool Compare(int a, Comparison c, int b) 
    { 
     if (c == Comparison.GreaterThan) 
      return a > b; 
     else if (c == Comparison.LessThan) 
      return a < b; 
     else 
      throw new ArgumentException(); 
    } 

    public void Run() 
    { 
     int i = 50; 
     int increment = -1; 
     int l = 0; 
     Comparison c = Comparison.GreaterThan; 
     for (i; Compare(i, c, l); i = i + increment) 
     { 

     } 
    } 
1
 Func<int, int, bool> o = (x, y) => x > y; 

     int i = 50; 

     int increment = -1; 

     int l = 0; 

     for(; o(i, l) ; i = i + increment) 
     { 
      //code 
     } 

o deshacerse de l por completo:

 Predicate<int> o = (x) => x > 0; 

     int i = 50; 

     int increment = -1; 

     for(; o(i) ; i = i + increment) 
     { 
      //code 
     } 
Cuestiones relacionadas