.NET 技术问题:将整数强制转换为十进制数时出错

6

为什么会出现这种情况:

(new[]{1,2,3}).Cast<decimal>();

导致“无效的强制类型转换异常:指定的转换无效。”

2个回答

11

是的,Cast 不会这样做。基本上它只进行引用转换和取消装箱转换 - 不会在不同值类型之间进行转换。

改用这个:

(new[]{1,2,3}).Select(x => (decimal)x)

请注意,在.NET 3.5 SP1之前,Cast方法进行了比现在更多的转换。我不知道它是否能在那时工作,但现在肯定不能。


有关为什么从装箱的int到非装箱的decimal的拆箱转换不起作用的一些想法,请参见http://blogs.msdn.com/ericlippert/archive/2009/03/19/representation-and-identity.aspx了解详细信息。 - Eric Lippert
@Eric:我总是忘记CastIEnumerable(因此对象)上而不是IEnumerable<T>上 - 因此它是一种拆装箱转换而不是两个值类型之间的转换。 (在那种情况下,直接转换也无法工作)。 不过话说回来,我永远找不到你解释Cast之前的用途(在SP1之前)的帖子。 - Jon Skeet
你找不到我写的那个,因为那不是我写的。是我的经理 Ed 写的。http://blogs.msdn.com/ed_maurer/archive/2008/02/16/breaking-change-in-linq-queries-using-explicitly-typed-range-variables.aspx - Eric Lippert
@Eric:啊,这就解释了。我以为你提到过参与审核原始代码的项目,或者那是另一个人…… - Jon Skeet
嗯,也许我写了一些关于那个的东西。我确实审查了原始代码,但当时没有意识到它是一个合理的实现,与方法指定的设计相反,并且非常慢。 (我以为我们改变了设计;不,只是实现!)很遗憾我们进行了破坏性的二进制更改,但是判断效能增益和语义正确性值得承受这种痛苦的打破。也许我在某个时候在博客或书评笔记中提到过。 - Eric Lippert

3

Cast(强制转换)和Convert(类型转换)是不同的概念。

使用Cast扩展方法时,它会根据继承结构尝试将项目强制转换。由于int并不是从decimal派生的,因此无法使用Cast进行转换。请改用以下方法:

(new[] {1,2,3}).Select(x => (decimal)X);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接