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

时间:2016-03-16 10:12:29

标签: c# foreach ienumerable

我编写了一个实现IEnumerable<T>的通用类:

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

    public IEnumerator GetEnumerator()
    {
        ...
    }
}

所以我可以用foreach迭代这个类的对象,但是如果我更改了foreach变量的类型,编译器不会给我一个错误,我可以编写这段代码而不会出现编译错误:

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

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

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

无法转换类型&#39; int&#39;到&#39;字符串&#39;

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

1 个答案:

答案 0 :(得分: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();
    }
}