尝试以下代码
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();
}
您认为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可以成功运行,返回正确的结果。
任何人都希望在他/她的机器上尝试这个并报告结果或解释为什么会这样?
答案 0 :(得分:18)
如果您希望它以任何方式工作,请改用Select
。
return intColor.Select(i=>(Color)i).ToList();
至于为什么......?
答案 1 :(得分:5)
Cast扩展方法使用迭代器,在接下来的移动中,将原始枚举器的输出存储在对象变量中(根据需要进行装箱)然后尝试将其转换为结果类型。
盒装形式的值类型不会像对待取消装箱时那样响应转换操作(可以进行各种自动转换),而只允许转换为原始的未装箱形式。
我认为Cast扩展的先前实现要么完全不同,要么为枚举类型转换为整数形式有一些特殊的外壳(这很棘手,因为你必须处理所有可能的形式)
Marc关于正确解决方案的答案是完全正确的,并且实际上比上述拳击原因更有效。
答案 2 :(得分:4)
您可以阅读SP1与.net 3.5框架in the release notes的原始版本之间的区别。
以下是针对此特定问题的说法:
在LINQ查询表达式中 非通用集合,如 System.Collections.ArrayList,from 查询的子句被重写 编译器包含一个调用 演员。演员转换 类型的所有元素类型 在from子句中指定的 查询。另外,在原版中 发布版本的Visual C#2008 ,. Cast操作员也执行一些操作 价值类型转换和 用户定义的转换。然而, 这些转换是由 请改用System.Convert类 标准C#语义。这些 转换也会造成重大影响 某些表现问题 场景。在Visual C#2008 SP1中, Cast运算符被修改为throw 数字的InvalidCastException 值类型和用户定义 转换。这种变化消除了 两者都是非标准的C#强制转换 语义和性能问题。 这种变化在图中说明 以下示例。
您还可以在this blog post中获取更多详细信息。