无法(或能够)列出<int> .Cast <Enum>()?

Gra*_*ton 9 c#

请尝试以下代码

public enum Color
{
    Blue=1,
    Red=2, 
    Green=3 
}

public List<Color> ConvertColorEnum()
{
    var intColor = new List<int>(){1,2,3};
    return intColor.Cast<Color>().ToList();
}
Run Code Online (Sandbox Code Playgroud)

你认为它ConvertColorEnum()会返回一个颜色列表,即List<Color>(){Color.Blue, Color.Red, Color.Green}

我在2台机器上进行了测试,一台使用.net 3.5(mscorlib版本2.0.50727.1433),另一台使用.net 3.5 SP1(mscorlib版本2.0.50727.3082).结果不同 - .net 3.5抛出一个InvalidCastException因为无法将整数转换为枚举,而.net 3.5 SP1可以成功运行,返回正确的结果.

任何人都想在他/她的机器上试一试并报告结果或解释为什么会这样?

Mar*_*ell 19

如果您希望它以任何方式工作,请Select改用.

return intColor.Select(i=>(Color)i).ToList();
Run Code Online (Sandbox Code Playgroud)

至于为什么......?


Shu*_*oUk 5

Cast扩展方法使用迭代器,在接下来的移动中,将原始枚举器的输出存储在对象变量中(因此根据需要进行装箱),然后尝试将其转换为结果类型.

盒装形式的值类型不会像取消装箱时那样响应转换操作(可以进行各种自动转换),而只允许转换为原始的未装箱形式.

我可以想象,Cast扩展的先前实现要么完全不同,要么为枚举类型转换为整数形式有一些特殊的外壳(这很棘手,因为你必须处理所有可能的形式)

Marc关于正确解决方案的答案是完全正确的,并且实际上比上述拳击原因更有效.


Jb *_*ain 4

您可以在发行说明中了解 SP1 与 .net 3.5 框架原始版本之间的差异。

以下是针对这个特定问题的说法:

在针对非泛型集合(例如 System.Collections.ArrayList)的 LINQ 查询表达式中,查询的 from 子句由编译器重写以包含对 Cast 运算符的调用。Cast 将所有元素类型转换为查询中 from 子句中指定的类型。此外,在 Visual C# 2008 的原始发行版本中,Cast 运算符还执行一些值类型转换和用户定义的转换。但是,这些转换是通过使用 System.Convert 类而不是标准 C# 语义来执行的。在某些情况下,这些转换还会导致严重的性能问题。在 Visual C# 2008 SP1 中,Cast 运算符已修改为针对数值类型和用户定义的转换引发 InvalidCastException。此更改消除了非标准 C# 转换语义和性能问题。以下示例说明了此更改。

您还可以在此博文中获取更多详细信息。