为什么我在通过 IEnumeable<T> 更改 foreach 类型时没有出现编译器错误?

Why do I not get a compiler error in change of type of foreach over IEnumeable<T>?

我写了一个实现 IEnumerable<T>:

的通用 class
public class EnumerableObject<T> :  IEnumerable<T>
{
    IEnumerator<T> IEnumerable<T>.GetEnumerator()
    {
        ...
    }

    public IEnumerator GetEnumerator()
    {
        ...
    }
}

所以我可以用 foreach 遍历这个 class 的对象,但是如果我改变 foreach 变量的类型,编译器不会给我一个错误,我可以在没有编译器错误的情况下编写这段代码:

foreach (string item in new EnumerableObject<int>())
{
    ....
}

但是如果我遍历通用列表,我会遇到编译器错误:

foreach (string item in new List<int>())
{
    ...
}

Cannot convert type 'int' to 'string'

我认为 List<T> class 条件就像我的 class EnumerableObject 但为什么我没有遇到编译器错误?

发生的事情是,因为您的非泛型 GetEnumerator 方法是 public,它是隐式使用的 foreach 语句。因此,它实际上是 returns 一个非泛型 IEnumerator,允许您编写 foreach (string item in new EnumerableObject<int>()),它会在 运行 时爆炸。

如果将非泛型 GetEnumerator 方法设为私有,您将看到编译时警告。你实际上应该反过来做:

public class EnumerableObject<T> : IEnumerable<T>
{
    public IEnumerator<T> GetEnumerator()
    {
        // Implement.
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}