为什么我会收到 InvalidCastException?
我在 c# 中有以下代码片段,
List<int> list = new List<int>() { 1, 23, 5, 3, 423, 3 };
var query = list.Cast<double>().Select(d => d);
try
{
foreach (var item in query)
{
Console.WriteLine(item);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
它可以完美编译,但是当我执行此代码时,我遇到了异常。
I have following code snippet in c#
List<int> list = new List<int>() { 1, 23, 5, 3, 423, 3 };
var query = list.Cast<double>().Select(d => d);
try
{
foreach (var item in query)
{
Console.WriteLine(item);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
It's compile perfectly,but when i am executing this I am getting exception.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
因为您是从 int 类型转换为 double,所以这不是转换,而是类型转换,这与一般情况下将 int 类型转换为 double 有所不同。
Cast
扩展方法使用 IL 指令unbox.any
而像这样的 C# 强制转换
实际上会导致 IL 指令
从根本上将类型拆箱为不同类型是错误的这就是为什么你会得到例外。
这个问题有相同的答案,还链接到 博客埃里克·利珀特 (Eric Lippert) 发表的文章。
Because you're typecasting from an int to double, it's not a conversion it's a type cast and this is somewhat different from when you cast int to double in the general case.
The
Cast<T>
extension method uses the IL instructionunbox.any
While a C# cast like this
Actually results in the IL instruction
Fundamentally unboxing an type as a different type is wrong and that's why you get the exception.
This question has the same answer and also links to a blog post by Eric Lippert.
list
包含ints
,您尝试将其转换为double
。将查询更改为Update
以下是
Enumerable.Cast
(.NET 4) 的源代码:如您所见,
CastIterator
尝试强制转换object
(在本例中是装箱的int
)到double
。仅当目标类型与装箱的原始类型完全相同时,拆箱操作才会成功,因此会引发异常。 John Leidegren 的此链接提供详细解释。list
containsints
, which you attempt to cast todouble
. Change your query toUpdate
Here's the source for
Enumerable.Cast
(.NET 4):As you can see, the
CastIterator
attempts to cast anobject
(which in this case is a boxedint
) to adouble
. Unboxing operations only succeed if the target type is exactly the same as the original type that was boxed, so an exception is thrown. This link that John Leidegren provided explains in detail..NET Framework 类型转换和 C# 类型转换之间存在差异。它们不一样。 “将 int 转换为 double”是 C# 语言的一项功能,也是该语言独有的功能。
为此,C# 编译器可以使用特殊指令将 int 转换为 double。编译器在编译时知道源类型是“int”,目标类型是“double”,因此可以生成正确的指令。这实际上并不是 .NET Framework 意义上的类型转换。
System.Int32 无法类型转换为 System.Double。 Cast 扩展方法是在不知道源集合和目标集合的确切类型的情况下编译的,因此没有生成用于处理C# 特定功能的特殊指令。为 Cast 扩展方法生成的唯一代码是普通的 .NET 类型转换(将类转换为它们的基类型、转换为对象以及将类型转换为它们实现的接口)。
There is a difference between a .NET Framework type-cast and a C# type conversion. They are NOT the same. "Casting" int to double is a feature of the C# language, and of the language alone.
The C# compiler can convert an int to double using a special instruction for this purpose. The compiler knows, at compile time, that the source type is "int", the destination type is "double", and therefore can generate the proper instruction. This is not really a type cast in the .NET Framework sense.
System.Int32 cannot be type-cast to System.Double. The Cast extension method was compiled without knowing the exact types of the source and the destination collections, and therefore no special instructions for handling C# specific features were generated. The only code that is generated for the Cast extension method is a normal .NET type cast (casting classes to their base types, casting to object, and casting types to the interfaces they implement).