没有为类型'System.Byte'和& # 39;System.Byte& # 39;

本文关键字:System Byte 类型 | 更新日期: 2023-09-27 18:05:53

我正在研究一个动态构造lambda表达式的项目。在这个特定的场景中,我动态地构造了一个表达式,它等于下面这个表达式:



字节j = 1;
var firstConstant = Expression.Constant(i);
var secondConstant = Expression.Constant(j);var lambda = Expression. lambda(表达式)添加(firstConstant secondConstant));
.DynamicInvoke lambda.Compile () ();

我知道基本类型没有操作符重载,编译器实际上在添加之前将变量/常量强制转换为int,结果返回为字节,因此引发异常。我的问题是,在不知道类型和不丢失一些数据的情况下执行添加操作的逻辑是什么,以防我需要处理浮点类型?

没有为类型'System.Byte'和& # 39;System.Byte& # 39;

基本上,我会有条件地测试每个操作数的Type,看看它是否为byte, sbyte等,并在必要时引入Expression.Convert

可能值得看看c#编译器为:

生成了什么
Expression<Func<byte, byte, int>> expr = (a, b) => a + b;

…然后试着用你自己的代码来生成正确的东西。

try

byte i = 1; 
byte j = 1; 
var firstConstant = Expression.Constant(i.GetType () == typeof (Byte) ? (int) i : i); 
var secondConstant = Expression.Constant(j.GetType () == typeof (Byte) ? (int) j : j);
var lambda = Expression.Lambda(Expression.Add(firstConstant, secondConstant));    
lambda.Compile().DynamicInvoke();

这样,即使不是字节,也不会丢失任何内容。
还要注意的是,执行byte r = i + j;会给你编译时的错误,关于"没有从int到byte的自动转换"。

这可能是不可能的。表达式。Add不执行溢出检查,它查找Binary +操作符的实现。另一个重载允许指定MethodInfo来选择执行Add的方法。

如果你能确保你所有的类型进入,支持这个方法,你可以使用上面的逻辑。因为定义了二进制+操作符,所以它可以在短时间内工作。系统不存在同样的情况。字节类,因此就有问题了。即使使用编译器实现,也不能这样做:

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?)