C# 未为“System.Byte”和“System.Byte”类型定义二进制运算符Add

C# 未为“System.Byte”和“System.Byte”类型定义二进制运算符Add,c#,expression,C#,Expression,我正在从事一个动态构造lambda表达式的项目。 在s的特定场景中,我动态构建了一个表达式,该表达式等于: 字节i=1; 字节j=1; var firstConstant=表达式.Constanti; var secondConstant=表达式.Constantj; var lambda=Expression.LambdaExpression.AddfirstConstant,secondConstant; lambda.Compile.DynamicInvoke 我知道基元类型没有运算符重载

我正在从事一个动态构造lambda表达式的项目。 在s的特定场景中,我动态构建了一个表达式,该表达式等于:

字节i=1; 字节j=1; var firstConstant=表达式.Constanti; var secondConstant=表达式.Constantj; var lambda=Expression.LambdaExpression.AddfirstConstant,secondConstant; lambda.Compile.DynamicInvoke

我知道基元类型没有运算符重载,编译器实际上在加法之前将变量/常量转换为int,并将结果转换回byte,我不知道,因此引发了异常。
我的问题是,如果我需要处理浮点类型,在不知道类型和不丢失一些数据的情况下执行add操作的逻辑是什么

这可能是不可能的。表达式.Add不执行溢出检查,它查找二进制+运算符的实现。另一个重载允许指定MethodInfo以选择要执行添加的方法

如果可以确保所有类型都支持此方法,那么可以使用上述逻辑。因为定义了二进制+运算符,所以它的工作时间很短。System.Byte类中不存在相同的问题,因此存在问题。即使使用编译器实现,也无法执行以下操作:

byte i = 1;
byte j = 2;
byte sum = i+j; // Cannot implicitly convert type 'int' to 'byte'. An explicit conversion exists (are you missing a cast?)
试一试

这样你就不会失去任何东西,如果它不是一个字节。。。
还要注意,执行字节r=i+j;给出编译时错误,即没有从int到byte的自动转换。

基本上,我会有条件地测试每个操作数的大小,看看它是否是byte、sbyte等,并引入一个表达式。必要时进行转换

可能值得一看C编译器生成的内容:

Expression<Func<byte, byte, int>> expr = (a, b) => a + b;

。。。然后尝试使用自己的代码生成正确的内容。

我还注意到,对于其他类型,它实际上是有效的-两个short常量。根据msdn,没有运算符重载简言之,我知道我可以做到这一点。我的问题是是否有一个系统来检查可以通过添加操作处理的类型,为什么添加操作对某些类型有效而对其他类型无效?您可以使用变量类型的反射来查看它们是否支持添加方法/运算符,并按照表达式的说明进行操作。添加本身就是这样做的。。。另一个选项是提供作为MethodInfo对象执行操作的方法,作为Expression.Add的第三个参数。
Expression<Func<byte, byte, int>> expr = (a, b) => a + b;