How to use MiscUtil.Operator on System.Byte?

I have been using MiscUtil Operators for a while without any big problems. But now I found what really bothered me:

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

The simple expected result of this equation should be result == 42 , but unfortunately this raises an InvalidOperationException :

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

Having examined this strange behavior in more detail, you will find that System.Byte does not really implement these operators. In C #, these types will be implicitly converted to Int32 and which implement these operators.

So, the question is: is there a chance to get MiscUtil to work with byte and sbyte ?

+4
source share
2 answers

Technically, int , etc. also do not implement these operators. They are not provided by "operators" in the usual sense (which is associated with static- call ), but represented directly by the add operation code. Ultimately, the failure in this case actually comes from the 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 

To fix this, MiscUtil would have to use special versions of byte / sbyte ; sort of:

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

But! It has been a long time since I knew my keys to Jon repo, p

Oddly enough, however, it’s not so difficult to implement the whole thing in raw IL ... I actually stumbled upon (on a USB stick) a very old .NET 2.0 (ie before Expression ) version of the "generic operators", which I wrote many years ago that he could do this job. Or easier: just put the MiscUtil file locally to handle byte / sbyte .

+5
source

Thanks to Marc's answer, I pinned my local version of MiscUtil. Using the ExpressionUtil.cs file, I applied the following patch:

 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) 

So, maybe one brilliant day the official version will be updated, or anyone who needs it can take it from here and apply the fix locally.

+2
source

All Articles