2011-08-18 69 views
2

我正在处理一个动态构建lambda表达式的项目。 在的具体方案中,我动态构造它等于这一个的表达式:二元运算符添加没有为'System.Byte'和'System.Byte'类型定义

字节I = 1;
字节j = 1;
var firstConstant = Expression.Constant(i);
var secondConstant = Expression.Constant(j);
var lambda = Expression.Lambda(Expression.Add(firstConstant,secondConstant));
lambda.Compile()。DynamicInvoke();

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

+0

我也注意到,与其他类型其实际工作 - 两个常量的短。 – Sagi

回答

2

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

它可能在什么C#编译器生成值得期待:

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

...然后尝试让自己的代码来生成正确的事情。

0

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

如果你可以确保你所有的类型进入,支持这种方法,你可以使用上面的逻辑。它确实可行,因为二元运算符是定义的。 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?) 
+0

根据msdn,没有运营商重载简而言之http://msdn.microsoft.com/en-us/library/system.int16.aspx – Sagi

1

尝试

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的自动转换”。

+0

我知道我可以做到这一点。我的问题是,是否有一个系统用于检查可以使用添加操作处理的类型,以及为什么添加操作对某些类型有效并且对其他类型无效? – Sagi

+0

您可以在变量的类型上使用Reflection来查看它们是否支持Add方法/运算符,并按照Expression.Add本身如何执行此操作的描述(http://msdn.microsoft.com/zh-cn/library/ bb354402.aspx)...另一个选项是提供Method作为MethodInfo对象执行操作,作为Expression.Add的第三个参数。 – Yahia

相关问题