【问题标题】:Can we use GetEnumerator() without using IEnumerable interface?我们可以在不使用 IEnumerable 接口的情况下使用 GetEnumerator() 吗?
【发布时间】:2011-02-23 17:54:27
【问题描述】:

我有一个名为 Primes 的类,该类实现了 GetEnumerator() 而不实现 IEnumerable 接口。

public class Primes
{
    private long min;
    private long max;

    public Primes()
        : this(2, 100)
    {
    }

    public IEnumerator GetEnumerator()
    {...}

我不明白。我错过了什么吗?

【问题讨论】:

    标签: c# ienumerator


    【解决方案1】:

    首先,正如其他人所说,您可以在不实现接口的情况下引入自己的方法 - 您可以编写自己的 Dispose 方法而不实现 IDisposable 等。对于众所周知的接口,我建议这几乎是一个坏事想法(因为读者会有一定的期望)但它是完全有效的。

    更重要的是,C# 中的foreach 语句可以在不涉及IEnumerable 的情况下工作。编译器有效地在名称GetEnumerator()CurrentMoveNext() 上执行编译时鸭子类型。这主要是为了在泛型之前允许 C# 1 中的强类型(和非装箱)迭代。有关详细信息,请参阅 C# 3 规范的第 8.8.4 节。

    但是,如果您确实希望能够轻松地将实例的内容作为集合进行迭代,那么现在这样做通常不是一个好主意 - 实际上我建议实现 @987654328 @ 而不仅仅是IEnumerable

    【讨论】:

    • 如果您的枚举器是struct,那么跳过接口实际上可能是一个好* 的想法。通过实现接口,您将允许开发人员无意中引入枚举器的装箱,无论它被引用为IEnumerable<T>,这通常是这种情况,例如在LINQ.
    • @l33t:我希望至少有一个返回IEnumerable<T>的方法,以便满足需要方便但不介意装箱惩罚的用户。跨度>
    【解决方案2】:

    是的,你可以。即使您可以在foreach 中使用它。唯一的问题是这个类的对象虽然实现了需要的方法,但不能转换为IEnumerable

    【讨论】:

      【解决方案3】:

      没有理由你必须实现IEnumerable 来创建一个名为GetEnumerator 的函数,它返回一个IEnumerator,这只是意味着你将无法为某事提供该类型的实例需要IEnumerable

      【讨论】:

        【解决方案4】:

        接口确保契约,这并不意味着您不能在不隐含接口的类上拥有与接口中的签名相同的方法。

        【讨论】:

          猜你喜欢
          • 2016-09-12
          • 1970-01-01
          • 2018-08-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-01-13
          相关资源
          最近更新 更多