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

Rez*_*eni 2 c# ienumerable foreach

我写了一个实现的泛型类IEnumerable<T>:

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

    public IEnumerator GetEnumerator()
    {
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

所以我可以迭代这个类的对象,foreach但如果我更改foreach变量的类型,编译器不给我一个错误,我可以编写此代码没有编译器错误:

foreach (string item in new EnumerableObject<int>())
{
    ....
}
Run Code Online (Sandbox Code Playgroud)

但是,如果我遍历一个通用列表,我得到一个编译器错误:

foreach (string item in new List<int>())
{
    ...
}
Run Code Online (Sandbox Code Playgroud)

无法将类型'int'转换为'string'

我认为List<T>类条件就像我的类EnumerableObject,但为什么我的情况下没有得到编译器错误?

Yuv*_*kov 8

会发生什么是因为你的非泛型GetEnumerator方法是public,隐含地使用的是foreach语句.因此,它有效地返回非泛型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();
    }
}
Run Code Online (Sandbox Code Playgroud)