【发布时间】:2011-11-27 14:36:08
【问题描述】:
3 个问题:
1) 为什么输出取自 NON 泛型函数?
2) 为什么我必须实现 ALSO 非泛型函数?
3) 如果我想查看通用函数输出(int 的)我需要做什么?
【问题讨论】:
标签: c# .net generics ienumerable
3 个问题:
1) 为什么输出取自 NON 泛型函数?
2) 为什么我必须实现 ALSO 非泛型函数?
3) 如果我想查看通用函数输出(int 的)我需要做什么?
【问题讨论】:
标签: c# .net generics ienumerable
foreach 关键字根本不需要集合实现IEnumerable;相反,它将调用任何已定义的 GetEnumerator 方法。
出于兼容性原因,IEnumerable<T> 实现 IEnumerable。
您应该显式实现IEnumerable.GetEnumerator(),并让普通方法返回IEnumerator<T>。
如果类有一个普通的GetEnumerator() 方法(与显式接口实现相反),编译器会调用它。
规范说:
- 否则,判断X类型是否有合适的GetEnumerator方法:
- 在类型 X 上执行成员查找,带有标识符 GetEnumerator 并且没有类型参数。如果成员查找没有产生匹配, 或者它会产生歧义,或者产生不是方法的匹配 组,检查可枚举接口,如下所述。它是 建议在成员查找产生时发出警告 除了方法组或不匹配之外的任何内容。
- 使用生成的方法组和空参数列表执行重载解析。如果重载决议导致没有 适用的方法,导致歧义,或导致单一 最好的方法,但该方法是静态的或非公开的,请检查 一个可枚举的接口,如下所述。建议一个 如果重载决议产生除 明确的公共实例方法或没有适用的方法。
- [...]
- 否则,请检查可枚举接口:
【讨论】:
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。
【讨论】:
您需要同时实现这两个,因为IEnumerable<T> 派生自IEnumerable。要调用显式实现的方法,您需要强制转换为该接口。
但通常你显式地实现非泛型方法和隐式地实现泛型方法。这样foreach 将使用通用方法。 foreach 对集合的类型使用 GetEnumerator() 方法,如果此方法不存在,则仅回退到接口方法。
典型的实现是:
public IEnumerator<int> GetEnumerator()
{
...
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return GetEnumerator();//Forward to strongly typed version
}
【讨论】:
return GetEnumerator();//Fo 有错误:迭代器不能包含返回语句...
yields。