我注意到IEnumerable(Generics)需要实现两种方法:
1。 IEnumerator<T> GetEnumerator()
2。 IEnumerable.GetEnumerator()
方法
(http://msdn.microsoft.com/en-us/library/19e6zeyy.aspx)
什么是#2 以及我应该如何定义/实施?
从我玩一些代码开始,似乎在foreach循环中调用了IEnumerator GetEnumerator()。 #2 IEnumerable.GetEnumerator在哪里发挥作用?
我正在完成配方6.1在Oreilly的C#3.0 Cookbook中创建一个泛型类型的迭代器,我收到一个错误,因为#2没有实现(它没有包含在配方代码中)。
谢谢!
答案 0 :(得分:9)
第一个是通用的GetEnumerator,而第二个是非泛型的。它们在功能上完成相同的工作,但非泛型只能返回object
类型。
实现这些的最简单方法是实现通用版本,然后为非泛型提供:
IEnumerator IEnumerable.GetEnumerator() {
return GetEnumerator();
}
答案 1 :(得分:2)
非通用的IEnumerable接口用于反向兼容,它还以非通用方式访问通用IEnumerable接口非常有用。
你只能实现IEnumerable.GetEnumerator成员,而只是明确实现其他界面,如
IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); /*generic method call*/ }
答案 2 :(得分:1)
#2是来自GetEnumerator
接口的IEnumerable
方法的显式非泛型实现。您的示例中的#1是GetEnumerator()
接口的IEnumerable<T>
实现。
IEnumerable.GetEnumerator()
可以调用与IEnumerable相同的底层代码,它不是强类型的(返回对象而不是强类型的IEnumerator)。
答案 3 :(得分:1)
您只需要定义泛型(在我的示例中返回String),然后告诉非泛型GetEnumerator方法调用泛型GetEnumerator(返回Object。)
class Foo : IEnumerable<string>
{
public IEnumerator<string> GetEnumerator()
{
foreach (string value in new[] { "a", "b", "c" })
{
yield return value;
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
答案 4 :(得分:1)
第二个是针对.NET v1.1编写的代码,它不了解泛型。
通常,您只需返回通用GetEnumerator()
中的值IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
答案 5 :(得分:0)
要实现第二个接口,请执行一个只调用泛型接口的隐式实现的显式实现。像
这样的东西class FooCollection : IEnumerable<Foo>, IEnumerable
{
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public IEnumerator<Foo> GetEnumerator()
{
// return enumerator
}
}
编辑:从IEnumerable
继承是多余的,但是这个答案表明,当您继承IEnumerable<T>
时,两个接口都将被实现,因为IEnumerable<T>
派生自IEnumerable
{{1}}。
答案 6 :(得分:0)
通常你不应该再自己实现IEnumerable了。框架中有许多内置类,实现此接口有多种不同的方式来满足99%的需求。
但是,如果你愿意,IEnumerable,GetEnumerator()方法是一个将IEnumerator对象返回给调用foreach的客户端的方法。这个Ienumerator对象是跟踪集合中哪个元素是“下一个”的对象“当foreach”迭代“时,将返回一个。要使其工作,您必须定义一个将成为Enumerator的类(它必须实现IEnumerator,或者通常是IEnumerator)
作为示例(对于PersonCollection)
public IEnumerator GetEnumerator() { return new myTypeEnumerator(this); }
public class myTypeEnumerator : IEnumerator
{
int nIndex;
PersonCollection pers;
public myTypeEnumerator(PersonCollection myTypes)
{ pers = myTypes; nIndex = -1; }
public bool MoveNext() { return (++nIndex < pers.alPers.Count); }
public object Current { get { return (pers[nIndex]); } }
public void Reset() { nIndex = -1; }
}
这个和通用版本之间的唯一区别是通用版本是强类型的:
public IEnumerator<T> GetEnumerator() { return new myTypeEnumerator<T>(this); }
public class myTypeEnumerator<T> : IEnumerator<T>
{
int nIndex;
IList<T> tList;
public myTypeEnumerator(IList<T> listOfTs)
{
tList = listOfTs;
nIndex = -1;
}
public bool MoveNext() { return (++nIndex < tList.Count); }
public T Current { get { return (tList[nIndex]); } }
public void Reset() { nIndex = -1; }
}