C# 我们可以使用GetEnumerator()而不使用IEnumerable接口吗?

C# 我们可以使用GetEnumerator()而不使用IEnumerable接口吗?,c#,ienumerator,C#,Ienumerator,我有一个名为Primes的类,这个类实现了GetEnumerator(),而没有实现IEnumerable接口 public class Primes { private long min; private long max; public Primes() : this(2, 100) { } public IEnumerator GetEnumerator() {...} 我不明白。我遗漏了什么吗?是的,你可以。甚

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

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

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

    public IEnumerator GetEnumerator()
    {...}

我不明白。我遗漏了什么吗?

是的,你可以。甚至您也可以在
foreach
中使用它。唯一的问题是,此类对象无法强制转换为
IEnumerable
,尽管它们实现了所需的方法。

没有理由必须实现
IEnumerable
才能创建名为
GetEnumerator
的函数,该函数返回
IEnumerator
,这只意味着您将无法向需要
IEnumerable

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

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


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

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

如果您的枚举数是
结构
,则跳过接口实际上可能是一个好主意。通过实现这些接口,您将允许开发人员在枚举数被引用为
IEnumerable
的地方无意中引入枚举数的装箱,例如,在
LINQ
@l33t中:我至少会有一个返回
IEnumerable
的方法,这样那些想要方便但不介意拳击惩罚的用户就会满意。
public class Primes
{
    private long min;
    private long max;

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

    public IEnumerator GetEnumerator()
    {...}