Foreach可以抛出InvalidCastException吗?

时间:2009-06-04 10:44:02

标签: c# foreach language-design

想象一下以下代码:

class foreach_convert
{
    public static void method2()
    {
        List<IComparable> x = new List<IComparable>();
        x.Add(5);

        foreach (string s in x)
        {
            //InvalidCastException in runtime
        }
    }
}

我想知道,为什么这种foreach行为如此...而不是C#? 这里发生的是对子类的隐式强制转换,它容易出错,并且似乎在语言的其他任何地方都被禁止。或者我不对吗?

P.S。我问的原因是我的项目中的类似代码中有一个错误,我曾经在外部库中迭代自定义集合,这个集合被称为SomeTypeCollection,但实际上提供了一个集合基本类型项目,可能包含SomeOtherType项。我的错,但仍然没有语言,也没有编译器提供任何明确的提示/警告,这对C#来说很不寻常......

3 个答案:

答案 0 :(得分:22)

回想一下仿制药之前... foreach必须施展才能做出合理的事情:

foreach (string x in names)
{
    // ...
}

而不是:

foreach (object tmp in names)
{
    string x = (string) tmp;
    // ...
}

后者只是icky,IMO。提供隐式转换与语言的其他部分不同,但在绝大多数情况下使用起来更容易。

怀疑如果C#开始使用泛型扩展方法(那么我们可以使用OfTypeCast){ {1}}不会以完全相同的方式指定。

请注意foreach中更奇怪:类型根本不必实现foreach。只要它有一个IEnumerable方法返回一些反过来GetEnumeratorMoveNext()的东西,C#编译器就会很高兴。这意味着您可以在泛型之前实现“强类型迭代器”(以避免装箱)。

答案 1 :(得分:9)

使用C#3我正在使用 var - 所以我收到编译器警告。

答案 2 :(得分:4)

foreach适用于IEnumerable,它返回对象类型的对象。对于每个项目,对象将被转换为您提供的类型。

除非您在C#3.0中使用 var 。然后,类型将从IEnumerable<T>获取,如果它是由集合实现的。