C# - 迭代在没有显式IEnumerable的情况下工作

时间:2017-06-02 13:39:41

标签: c# iterator ienumerable

以下C#代码中的foreach工作正常,即使我没有做Days:IEnumerable。所以这看起来像一种鸭子打字。为什么这可能?我认为Days:IEnumerable是强制性的。

using System;
using System.Collections;
using System.Collections.Generic;



namespace ConsoleApplication1
{
    // works even if I does not
    // Days:IEnumerable
    public class Days
    {
        string[] tage = { "mon", "tue", "wed", "thu", "fri" };
        public IEnumerator GetEnumerator()
        {
            for (int i = 0; i < tage.Length; i++)
                yield return tage[i];
        }
    } 


    class Program
    {
        static void Main(string[] args)
        {
            Days daylist = new Days();
            foreach (string s in daylist) { Console.WriteLine(s); } 



        }

    }
}

3 个答案:

答案 0 :(得分:0)

不,你不需要那个界面。如果您尝试对不可枚举的数据类型foreach执行bool,则会出现此错误:

  

CS1579:foreach语句不能对'bool'类型的变量进行操作,因为'bool'不包含'GetEnumerator'的公共定义

因此要求很简单:该类必须具有公共GetEnumerator方法。

然后下一个错误告诉我们更多:

  

CS0202:foreach要求'Program.C.GetEnumerator()'的返回类型'void'必须具有合适的公共MoveNext方法和公共Current属性

所以这是一个使用foreach的有效实现,虽然它与调用永远不会结束;)

public class E
{
    public bool MoveNext() { return true; }

    public object Current { get { return null; } }
}

public class C
{
    public E GetEnumerator()
    {
        return new E();
    }
}

答案 1 :(得分:0)

就像你说的那样,这得益于Duck Typing接口不是强制性的。有关该主题,请参阅MSDN全文。 https://msdn.microsoft.com/en-us/magazine/mt797654.aspx

答案 2 :(得分:0)

根据C#语言规范,第8.8.4节&#34; foreach声明&#34; (https://msdn.microsoft.com/en-us/library/aa664754(v=vs.71).aspx

  

foreach语句的表达式类型必须是集合类型(如下定义)[...]

     

[...]如果类型C实现System.Collections.IEnumerable接口或通过满足以下所有条件来实现集合模式,则称其为集合类型:

     

C包含一个带有签名GetEnumerator()的公共实例方法,该签名返回struct-type,class-type或interface-type,在下文中称为E.

     

E包含一个带有签名MoveNext()和返回类型bool的公共实例方法。

     

E包含一个名为Current的公共实例属性,允许读取当前值。该属性的类型被称为集合类型的元素类型。

因此,不仅您的班级没有义务实施IEnumerable,而且您的GetEnumerator()方法也没有义务返回IEnumerator。返回类型所要做的就是使用正确的签名实现方法。