2008-10-05 10 views
6

No he usado mucho los genéricos y por lo tanto no puedo determinar si es posible convertir los siguientes tres métodos en uno usando genéricos para reducir la duplicación. En realidad, mi código actualmente tiene seis métodos, pero si puede resolverlo para los tres, el resto debería funcionar de todos modos con la misma solución.¿Cómo convertir estos 3 métodos en uno usando los genéricos C#?

private object EvaluateUInt64(UInt64 x, UInt64 y) 
    { 
     switch (Operation) 
     { 
      case BinaryOp.Add: 
       return x + y; 
      case BinaryOp.Subtract: 
       return x - y; 
      case BinaryOp.Multiply: 
       return x * y; 
      case BinaryOp.Divide: 
       return x/y; 
      case BinaryOp.Remainder: 
       return x % y; 
      default: 
       throw new ApplicationException("error"); 
     } 
    } 

    private object EvaluateFloat(float x, float y) 
    { 
     switch(Operation) 
     { 
      case BinaryOp.Add: 
       return x + y; 
      case BinaryOp.Subtract: 
       return x - y; 
      case BinaryOp.Multiply: 
       return x * y; 
      case BinaryOp.Divide: 
       return x/y; 
      case BinaryOp.Remainder: 
       return x % y; 
      default: 
       throw new ApplicationException("error"); 
     } 
    } 

    private object EvaluateDouble(double x, double y) 
    { 
     switch (Operation) 
     { 
      case BinaryOp.Add: 
       return x + y; 
      case BinaryOp.Subtract: 
       return x - y; 
      case BinaryOp.Multiply: 
       return x * y; 
      case BinaryOp.Divide: 
       return x/y; 
      case BinaryOp.Remainder: 
       return x % y; 
      default: 
       throw new ApplicationException("error"); 
     } 
    } 

Estoy construyendo un analizador simple expresión que luego tiene que evaluar las operaciones binarias simples como la suma/resta etc utilizo los métodos anteriores para obtener las matemáticas reales realizaron utilizando los tipos pertinentes. ¡Pero tiene que haber una mejor respuesta!

Respuesta

9

Los genéricos no son compatibles de forma nativa con la aritmética. Sin embargo, se puede hacer con .NET 3.5, like so. La clase de operador es parte de MiscUtil. Esto se convierte en:

public T Evaluate<T>(T x, T y) { 
     switch (Operation) 
     { 
     case BinaryOp.Add: 
      return Operator.Add(x, y); 
     case BinaryOp.Subtract: 
      return Operator.Subtract(x, y); 
    ... etc 

Puesto que usted está escribiendo un analizador de expresiones, que podría ser una buena idea utilizar la expresión directa, pero le invitamos a utilizar el anterior.

+0

Al contrario de la especulación popular, Marc y yo somos en realidad dos personas separadas. Parece que ocasionalmente compartimos una opinión. –

+0

Tal vez solo * pensamos * que ... alguna vez veas Fight Club? –

+0

Cerebros intercambiables? Guay. – EricSchaefer

4

Marc Gravell ha trabajado mucho para que las matemáticas genéricas sean viables. Consulte MiscUtil y general article about the issue.

El código en la versión actual de MiscUtil requiere .NET 3.5 debido a su uso de árboles de expresiones. Sin embargo, creo que Marc tiene una versión que también funciona con .NET 2.0. Si esto fuera útil para las personas, estoy seguro de que podríamos incorporarlo de alguna manera (posiblemente con una fachada en MiscUtil, que usaría la implementación adecuada en función de la versión de framework en tiempo de ejecución).

Para el futuro, me gustaría ver static interfaces que podría proporcionar una forma alternativa de trabajar con tipos matemáticos genéricos.

+0

Probablemente necesitaría volver a hacer el 2.0 - Creo que murió en un HDD, le envié por correo electrónico una copia una vez - no supongo que Aun así, no es una gran cantidad de trabajo ... –

+0

Es muy posible que lo tenga. No puedo verificarlo ahora, pero lo veré más adelante si me lo recuerdas. –