以下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); }
}
}
}
答案 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
。返回类型所要做的就是使用正确的签名实现方法。