【问题标题】:Why do I not get a compiler error in change of type of foreach over IEnumeable<T>?为什么在通过 IEnumerable<T> 更改 foreach 类型时不会出现编译器错误?
【发布时间】:2016-07-02 03:35:35
【问题描述】:

我写了一个实现IEnumerable&lt;T&gt;的泛型类:

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>())
{
    ...
}

无法将类型“int”转换为“string”

我认为List&lt;T&gt; 类条件就像我的类 EnumerableObject 但为什么在我的情况下没有出现编译器错误?

【问题讨论】:

  • 您正在尝试使用字符串迭代 int。那永远行不通。为什么要使用字符串?
  • @CathalMF,如果我完整阅读了问题,我会尝试模拟一个冲突的情况来澄清问题。

标签: c# foreach ienumerable


【解决方案1】:

发生的情况是,因为您的非通用 GetEnumerator 方法是 public,所以它是隐式使用的 foreach 语句。因此,它有效地返回一个非泛型IEnumerator,允许您编写foreach (string item in new EnumerableObject&lt;int&gt;()),它会在运行时爆炸。

如果您将非泛型 GetEnumerator 方法设为私有,您将看到编译时警告。您实际上应该以相反的方式进行:

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

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

【讨论】:

  • 你是对的......现在你应该用 swapperd GetEnumerator(): public IEnumerator&lt;T&gt; GetEnumerator() 和 IEnumerator IEnumerable.GetEnumerator() 向他展示“更正确的代码”
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-12-10
  • 2014-06-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-10
  • 1970-01-01
相关资源
最近更新 更多