3个问题:
1)为什么输出来自 NON 泛型函数?
2)为什么我有来实现NON泛型函数?
3)如果我想查看通用函数输出(int的),我需要做什么?
答案 0 :(得分:8)
foreach
关键字不要求集合实现IEnumerable
;相反,它会调用任何已定义的GetEnumerator
方法。
IEnumerable<T>
出于兼容性原因实施IEnumerable
。
您应该明确地实施IEnumerable.GetEnumerator()
并使常规方法返回IEnumerator<T>
。
如果类具有正常的GetEnumerator()
方法(而不是显式接口实现),编译器将调用它。
规范说:
- 否则,确定类型X是否具有适当的GetEnumerator方法:
- 使用标识符GetEnumerator对类型X执行成员查找,而不使用类型参数。如果成员查找没有产生匹配, 或者它产生歧义,或产生不是方法的匹配 group,检查如下所述的可枚举接口。它是 建议在成员查找生成时发出警告 除方法组或不匹配的任何内容。
- 使用生成的方法组和空参数列表执行重载解析。如果重载决策导致否 适用的方法,导致歧义,或结果单一 最好的方法,但该方法是静态的或不公开的,检查 如下所述的可枚举接口。建议一个 如果重载决议产生除了一个以外的任 明确的公共实例方法或没有适用的方法。
- [...]
- 否则,请检查可枚举的界面:
答案 1 :(得分:6)
1)输出来自非泛型函数,因为它是隐式定义的(并且通用函数是显式定义的)。
2)IEnumerable<T>
继承自IEnumerable
,因此从IEnumerable<T>
继承的任何类型都必须实现IEnumerable
的成员
3)使通用定义隐式,非通用定义明确,例如
public class Class1 : IEnumerable<int>
{
public IEnumerator<int> GetEnumerator()
{
yield return 1;
yield return 2;
yield return 3;
yield return 4;
}
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
}
请注意,您可以从非泛型方法返回通用枚举器,因为IEnumerator<T>
继承自IEnumerator
。
答案 2 :(得分:3)
您需要同时实现这两项,因为IEnumerable<T>
派生自IEnumerable
。要调用显式实现的方法,您需要转换为该接口。
但通常你会显式地实现非泛型方法和隐式的泛型方法。那样foreach
将使用泛型方法。 foreach
对集合的类型使用GetEnumerator()
方法,如果此方法不存在,则仅回退到接口方法。
典型的实施是:
public IEnumerator<int> GetEnumerator()
{
...
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return GetEnumerator();//Forward to strongly typed version
}