Foreach 可以抛出 InvalidCastException 吗? [英] Foreach can throw an InvalidCastException?

查看:24
本文介绍了Foreach 可以抛出 InvalidCastException 吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

想象一下下面的代码:

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#?这里发生的是对子类的隐式转换,这很容易出错,并且似乎在语言的其他所有地方都被禁止.还是我不对?

I wonder, why is this foreach behavior so... not C#-like? What happens here is an implicit cast to a subclass, which is error-prone and seems to be banned in every other place in the language. Or am I not right?

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

P.S. The reason I'm asking is that I had a bug in the similar code in my project, where I used to iterate through a custom Collection from an external library, which was called like SomeTypeCollection, but in fact provided a collection of base type items and could have contained items of SomeOtherType. My fault, but still neither the language, nor the compiler provided any explicit hints/warnings, which is quite unusual for C#...

推荐答案

回想一下之前的泛型... foreach 必须强制转换,以便您可以做一些明智的事情,例如:

Think back to before generics... foreach had to cast so that you could do sensible things like:

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

代替:

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

IMO,后者太恶心了.提供隐式强制转换与语言的其他部分不同,但使其在绝大多数情况下更易于使用.

The latter is just icky, IMO. Providing an implicit cast is unlike the rest of the language, but makes it much easier to use in the vast majority of cases.

怀疑如果 C# 有泛型扩展方法开始(所以我们可以使用 OfTypeCast),foreach 不会以完全相同的方式指定.

I suspect that if C# had had generics and extension methods to start with (so we could use OfType and Cast) that foreach wouldn't be specified in quite the same way.

请注意,foreach 中还有更奇怪的地方:该类型根本不必实现 IEnumerable.只要它有一个 GetEnumerator 方法,该方法返回一些内容,而该方法又具有 MoveNext()Current,C# 编译器很高兴.这意味着您可以在泛型之前实现强类型迭代器"(以避免装箱).

Note that there's even more oddness in foreach: the type doesn't have to implement IEnumerable at all. So long as it has a GetEnumerator method which returns something which in turn has MoveNext() and Current, the C# compiler is happy. This meant you could implement a "strongly typed iterator" (to avoid boxing) before generics.

这篇关于Foreach 可以抛出 InvalidCastException 吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆