C# 关于IEnumerable<;T>;
我注意到IEnumerable(泛型)需要实现两种方法: 1<代码>IEnumerator GetEnumerator() 2C# 关于IEnumerable<;T>;,c#,c#-3.0,C#,C# 3.0,我注意到IEnumerable(泛型)需要实现两种方法: 1IEnumerator GetEnumerator() 2IEnumerable.GetEnumerator()Method () 什么是#2以及我应该如何定义/实施这一点 从我玩的一些代码来看,似乎IEnumerator GetEnumerator()是在foreach循环中调用的。 #2 IEnumerable.GetEnumerator在哪里发挥作用 在Oreilly的C#3.0食谱中,我浏览了recipe 6.1,在泛型类型上创
IEnumerable.GetEnumerator()
Method
()
什么是#2以及我应该如何定义/实施这一点
从我玩的一些代码来看,似乎IEnumerator GetEnumerator()是在foreach循环中调用的。
#2 IEnumerable.GetEnumerator在哪里发挥作用
在Oreilly的C#3.0食谱中,我浏览了recipe 6.1,在泛型类型上创建了迭代器,我遇到了一个错误,因为#2没有实现(它没有包含在配方代码中)
谢谢大家! #2是IEnumerable
接口中GetEnumerator
方法的显式非泛型实现#在您的示例中,1是针对IEnumerable
接口的GetEnumerator()
的实现
IEnumerable.GetEnumerator()
可以调用与IEnumerable相同的底层代码,但它不是强类型的(返回对象而不是强类型的IEnumerator)。第一个是通用的GetEnumerator,而第二个是非通用的。它们的功能相同,但非泛型只能返回对象
类型
实现这些功能的最简单方法是实现通用版本,然后为非通用版本提供:
IEnumerator IEnumerable.GetEnumerator() {
return GetEnumerator();
}
要实现第二个接口,请执行一个显式实现,该实现只调用泛型接口的隐式实现。差不多
class FooCollection : IEnumerable<Foo>, IEnumerable
{
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public IEnumerator<Foo> GetEnumerator()
{
// return enumerator
}
}
class FooCollection:IEnumerable,IEnumerable
{
IEnumerator IEnumerable.GetEnumerator()
{
返回GetEnumerator();
}
公共IEnumerator GetEnumerator()
{
//返回枚举器
}
}
Edit:从
IEnumerable
继承是多余的,但是这个答案表明,当您继承IEnumerable
时,这两个接口都要实现,因为IEnumerable
派生自IEnumerable,您只需要定义泛型接口(在我的示例中返回字符串)然后告诉非泛型GetEnumerator方法调用泛型GetEnumerator(返回Object)
类Foo:IEnumerable
{
公共IEnumerator GetEnumerator()
{
foreach(新[]{“a”、“b”、“c”}中的字符串值)
{
收益回报值;
}
}
IEnumerator IEnumerable.GetEnumerator()
{
返回GetEnumerator();
}
}
非泛型IEnumerable接口用于后端兼容性,它还提供了以非泛型方式访问泛型IEnumerable接口的非常有用的功能
您只能实现IEnumerable.GetEnumerator成员,只需明确实现其他接口,如
IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); /*generic method call*/ }
第二个是为.NETV1.1编写的代码,它不理解泛型
通常,您只需要让它从泛型GetEnumerator()返回值
一般来说,您不需要自己实现IEnumerable。框架中有许多内置类,它们实现这个接口,并通过各种不同的方式满足99%的需求
但是,如果需要,IEnumerable,GetEnumerator()方法将向调用foreach的客户端返回IEnumerator对象。此IEnumerator对象是跟踪集合中哪个元素是foreach“迭代”时要返回的“下一个”元素的对象。为此,必须定义一个类作为该枚举器(它必须实现IEnumerator,或一般称为IEnumerator)
例如(对于个人集合)
public IEnumerator GetEnumerator(){返回新的myTypeEnumerator(this);}
公共类myTypeEnumerator:IEnumerator
{
int-nIndex;
个人收集;
公共myTypeEnumerator(PersonCollection myTypes)
{pers=myTypes;nIndex=-1;}
public bool MoveNext(){return(++nIndex
此版本与泛型版本之间的唯一区别在于泛型版本是强类型的:
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; }
}
public IEnumerator GetEnumerator(){返回新的myTypeEnumerator(this);}
公共类myTypeEnumerator:IEnumerator
{
int-nIndex;
IList-tList;
公共myTypeEnumerator(IList listOfTs)
{
tList=列表OFTS;
nIndex=-1;
}
public bool MoveNext(){return(++nIndex
Wow可能重复。你们太棒了!谢谢你的帮助。是的,我所做的是在非泛型方法中返回GetEnumerator()。@x0n,这部分是好的,我的代码在接口继承声明部分是多余的,但它确实显示了发生了什么。实现通用接口需要实现非通用接口。但准确地说,IEnumerable
并没有实现IEnumerable
。不可能。回顾过去,我并不是想让你知道一点——一个简单的评论就足够了。我来倒过来。更新:除非您编辑您的问题以修复冗余,否则我无法撤销分数;-)是的,“implement”是个错误的动词。“源自”或“继承”是我的意思。Doh。
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
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; }
}