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

时间:2009-05-14 13:05:48

标签: 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();
}

您认为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可以成功运行,返回正确的结果。

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

3 个答案:

答案 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中获取更多详细信息。