LINQ表达式中关于显式范围变量的Bug
2008-02-16 23:07
302 查看
MSDN博客中的一篇文章提到了.NET 3.5 SP1会带来的处个修正,见以下代码:
var floats = new ArrayList { 2.5f, 3.5f, 4.5f };
var ints = from int i in floats
select i;
注意from后面声明的显式类型(int)。开发者会很自然地认为ints为[2,3,4],但在现在版本.NET 3.5环境下得到的却是[2,4,4]。
原来那段LINQ表达式将会被编译为以下方法调用:
var ints = floats.Cast<int>().Select<int,int>(i => i);
问题便出现在Cast这个扩展方法中,而Cast内部是通过调用Convert类的ToInt32方法转换ArrayList中元素类型的,而这个方法既不是对浮点数进行截去小数,也不是简单的round:
ToInt32方法的文档中是这样描述返回值的:
value rounded to the nearest 32-bit signed integer. If value is halfway
between two whole numbers, the even number is returned; that is, 4.5 is
converted to 4, and 5.5 is converted to 6.
这种数值转换的方式被称为Banker's rounding。
这是个程序语义的问题,将在以后的.NET Frameworkk 3.5 SP1中解决,估计只是修改Cast方法的实现。现在的应对方法是在一些应用场景中不使用显式范围变量。
var floats = new ArrayList { 2.5f, 3.5f, 4.5f };
var ints = from int i in floats
select i;
注意from后面声明的显式类型(int)。开发者会很自然地认为ints为[2,3,4],但在现在版本.NET 3.5环境下得到的却是[2,4,4]。
原来那段LINQ表达式将会被编译为以下方法调用:
var ints = floats.Cast<int>().Select<int,int>(i => i);
问题便出现在Cast这个扩展方法中,而Cast内部是通过调用Convert类的ToInt32方法转换ArrayList中元素类型的,而这个方法既不是对浮点数进行截去小数,也不是简单的round:
ToInt32方法的文档中是这样描述返回值的:
value rounded to the nearest 32-bit signed integer. If value is halfway
between two whole numbers, the even number is returned; that is, 4.5 is
converted to 4, and 5.5 is converted to 6.
这种数值转换的方式被称为Banker's rounding。
这是个程序语义的问题,将在以后的.NET Frameworkk 3.5 SP1中解决,估计只是修改Cast方法的实现。现在的应对方法是在一些应用场景中不使用显式范围变量。
相关文章推荐
- c# in deep 之对Linq表达式范围变量限制问题的一些解决办法
- JDK8的随笔(03)_Lambda表达式的变量使用范围讨论
- php--关于函数(2)变量范围
- 第七章 函数表达式和函数声明,关于this对象 ,私有作用域(function(){})() ,私有变量和特权方法
- javascript中关于变量定义及范围
- lambda表达式Bug——修改捕获变量失败
- 关于百度地图的补充:只显示屏幕范围内的marker(旋转时的bug)
- 关于变量定义的古怪bug
- 线程范围内共享变量的概念与作用以及ThreadLocal类及应用修复bug
- Javascript 中变量的作用范围引发的bug
- 关于 变量的范围
- C#中一道关于员工信息系统的题(主要考察LinQ和正则表达式验证)
- 关于web应用程序的范围与session变量丢失问题的深入研究!
- 关于js里面的变量范围
- vs2008 linq2sql继续挖掘bug:表达式列支持问题
- 关于C语言中 int型变量和unsigned int变量范围之间的关系
- 我好像又找到MS的一个BUG了,关于正则表达式的
- 一个讨论引发关于js中函数声明,函数表达式,形参与变量声明赋值引发的一些事
- 关于.NET 2.0中正则表达式的Bug
- 关于Mono使用linq查询的几个BUG