2013-01-16 3 views
4

J'utilise MiscUtil Opérateurs pendant un certain temps sans grands problèmes. Mais maintenant, je l'ai trouvé quelque chose qui me dérange vraiment:Comment utiliser MiscUtil.Operator sur System.Byte?

byte first = 13; 
byte second = 29; 

byte result = MiscUtil.Operator.Add(first, second); 

Le résultat simple attendu de cette équation devrait être result == 42 mais malheureusement cela jette un InvalidOperationException:

The binary operator Add is not defined for the types 'System.Byte' and 'System.Byte'. 

En examinant de plus près à ce comportement étrange vous découvrirez que System.Byte n'implémente pas vraiment ces opérateurs. Dans C#, ces types seront implicitement convertis en Int32 et cela implémentera ces opérateurs.

Donc la question est maintenant: Y at-il une chance d'obtenir MiscUtil de travailler avec byte et sbyte?

+0

Attention à ce que vous souhaitez. Ceci n'est pas supporté par Expression.Add() en raison de la grande chance pour le débordement non diagnostiquable. –

Répondre

5

Techniquement, int etc également ne pas implémenter ces opérateurs. Ils ne sont pas fournis par des "opérateurs" dans le sens normal (ce qui impliquerait un call statique), mais représentés directement par le code d'opération add. En fin de compte, l'échec dans ce cas est en réalité à venir de la Expression API:

var x = Expression.Parameter(typeof(byte)); 
var y = Expression.Parameter(typeof(byte)); 
var func = Expression.Lambda<Func<byte,byte,byte>>(
    Expression.Add(x,y), x, y).Compile(); // explodes here 

Pour fix il, MiscUtil devrait-cas particulier les versions byte/sbyte; quelque chose comme:

var x = Expression.Parameter(typeof(byte)); 
var y = Expression.Parameter(typeof(byte)); 
var func = Expression.Lambda<Func<byte,byte,byte>>(
    Expression.Convert(
     Expression.Add(
      Expression.Convert(x, typeof(int)), 
      Expression.Convert(y, typeof(int)) 
     ),typeof(byte)), x, y).Compile(); 

Cependant! Il y a longtemps que je connaissais mes clés pour le repo de Jon; p

Curieusement, il n'est pas si difficile d'implémenter le tout en IL brut ... Je suis tombé sur (sur un USB-drive) une très ancienne version .NET 2.0 (c'est-à-dire avant Expression) des "opérateurs génériques" que j'ai écrits il y a de nombreuses années, ce qui pourrait faire l'affaire. Ou plus facile: il suffit de patcher MiscUtil localement pour gérer byte/sbyte.

2

Grâce à la réponse de Marc, j'ai corrigé ma version locale de MiscUtil. Withing les ExpressionUtil.cs fichier i appliqué le correctif suivant:

Index: ExpressionUtil.cs 
=================================================================== 
--- ExpressionUtil.cs 
+++ ExpressionUtil.cs 
@@ -68,6 +68,18 @@ 
      { 
       try 
       { 
+     if (typeof(TArg1) == typeof(byte) 
+      || typeof(TArg1) == typeof(sbyte) 
+      || typeof(TArg2) == typeof(byte) 
+      || typeof(TArg2) == typeof(sbyte)) 
+     { 
+      return Expression.Lambda<Func<TArg1, TArg2, TResult>>(
+       Expression.Convert(body(
+         Expression.Convert(lhs, typeof(int)), 
+         Expression.Convert(rhs, typeof(int)) 
+        ), typeof(TResult)), lhs, rhs).Compile(); 
+     } 
+ 
        return Expression.Lambda<Func<TArg1, TArg2, TResult>>(body(lhs, rhs), lhs, rhs).Compile(); 
       } 
       catch (InvalidOperationException) 

Alors peut être un jour brillant la version officielle sera mis à jour, ou toute personne qui en a besoin peut le prendre d'ici et d'appliquer localement le patch .

Questions connexes