黑马程序员技术交流社区
标题:
foreach对象必须实现什么接口或方法?
[打印本页]
作者:
李行周
时间:
2012-11-18 23:16
标题:
foreach对象必须实现什么接口或方法?
本帖最后由 李行周 于 2012-11-27 00:24 编辑
foreach对象必须实现什么接口或方法?
作者:
吴瑞祥
时间:
2012-11-19 06:35
foreach是迭代循环语句吧
作者:
马毅
时间:
2012-11-19 08:55
IEnumerable接口,GetEnumerator方法
作者:
崔晓聪
时间:
2012-11-19 09:00
在使用foreach集合进行遍历的时候,要求被遍历的对象必须实现了 IEnumerable 接口,而该接口的唯一成员方法GetEnumerator返回实现了Ienumator接口的实例对象。
作者:
陈辉
时间:
2012-11-19 09:03
本帖最后由 陈辉 于 2012-11-19 09:10 编辑
1、源代码
static void Main(string[] args)
{
List<string> list = new List<string> { "Lucy", "Jim", "Tom" };
//-----------------------foreach实现的---------------------------------------
//foreach (string s1 in list)
//{
// Console.WriteLine(s1);
//}
//-----------------------foreach的内部实现机制--------------------------------
IEnumerator<string> enumerator = list.GetEnumerator();
while (enumerator.MoveNext())
{
string s1 = enumerator.Current;
Console.WriteLine(s1);
}
Console.ReadKey();
}
2、对foreach的内部实现机制的代码的解释:
a、List泛型类的GetEnumerator方法是在IEnumerable<T>接口定义的,因此List泛型类要实现IEnumerable<T>接口
b、 List泛型类的GetEnumerator方法 返回的是List<T>.Enumerator,而List<T>.Enumerator是在List泛型类 内部定义的一个结构,它实现了IEnumerator<T>接口,因此,要想用foreach,那么自定
义的类必须实现 IEnumerable或IEnumerable<T> 和IEnumerator 或 IEnumerator<T>
c、再调用 IEnumerator<T>接口 中的MoveNext方法,当调用一次MoveNext方法时,就遍历集合中的一个元素,并将当前遍历的元素保存到IEnumerator<T>接口 的Current属性中
MoveNext方法的内部实现(可以用.net reflector查看List泛型类 实现的MoveNext方法)
:
public bool MoveNext()
{
List<T> list = this.list; //获得List泛型集合
if ((this.version == list._version) && (this.index < list._size))
{
// list._items[this.index] ->获得当前遍历的元素
//并单签遍历的元素保存到IEnumerator<T>接口 的Current属性中
this.current = list._items[this.index];
this.index++;//index加1,以便下次调用MoveNext方法时,获取下一个元素
return true;
}
return this.MoveNextRare();
}
3、当在foreach中用其他集合时,foreach的内部实现机制和List泛型集合的实现大同小异。
作者:
王新阳
时间:
2012-11-19 10:01
能用foreach遍历访问的对象必须是集合或数组对象,而这些都是靠实现超级接口IEnumerator或被声明 GetEnumerator 方法的类型
作者:
静等花开
时间:
2012-11-19 10:20
平常使用foreach in 的时候都是用的系统定义好的集合类(实现ICollection接口)。比如 arrayList,stringDictionary ,数组等。这些是平台封装好的,已近实现了IEnumerator 接口了。要让自己写的类也能时候foreach 就必须 在编写类的时候实现该接口。这样就可以事后foreach遍历了。比如 定义一个 people 的类,实现了IEnumerator接口。有一个数组 People[] tempPeople ,那么 就可以用: foreach( p in tempPeople){ console.writeline(p.name);}这样就免去了用for 循环的麻烦。至于怎么样去实现Iemumerator接口。查一下MSDN 就可以啦。
作者:
王彬
时间:
2012-11-19 12:43
能用foreach遍历访问的对象必须是集合或数组对象,而这些都是靠实现超级接口IEnumerator或被声明 GetEnumerator 方法的类型
作者:
韩俊
时间:
2012-11-19 13:22
IEnumerable接口,GetEnumerator方法
作者:
刘俊红
时间:
2012-11-26 23:42
本帖最后由 刘俊红 于 2012-11-26 23:45 编辑
楼主这个问题《
C#图解教程2010 20.枚举数和迭代器》
讲的极其详细和清楚。
我的总结如下:
一个类的数据成员能被foreach迭代的本质是什么?[_并且没有共享混乱出现]
本质:该类具有一个签名为publict ReturnedType GetEnumerator()的方法,ReturnType类型满足条件:一个公共的MoveNext()方法,一个公共的Current属性。
所以
1)类并不需要必须实现IEnumerable <T>或者IEnumerable接口,只需要一个满足上面签名的方法。
2)这个方法的返回值不需要必须实现IEnumerator <T>或者IEnumertor接口,只需要有一个公共MoveNext()方法和一个公共Current属性
【当然,你必须在这两个里面实现正确的逻辑】
一个类的数据成员能被foreach迭代的本质是它有一个能返回枚举数的GetEnumerator()方法。
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2