- 浏览: 2068569 次
- 性别:
- 来自: 厦门
文章分类
- 全部博客 (1409)
- asp/asp.net学习 (241)
- oracle (10)
- delphi (295)
- java (27)
- pb (1)
- 每日点滴 (49)
- 学习方法 (40)
- 思想方面 (104)
- C语言 (5)
- C++ (1)
- 代码重构经验 (5)
- 软件工程 (3)
- 数据库 (99)
- 英语学习 (3)
- mysql (1)
- 该关注的网站或者网页 (42)
- 总结 (7)
- 要去做的事情 (33)
- 算法 (1)
- 网络方面 (29)
- 随感 (96)
- 操作系统 (36)
- UML (12)
- 常用工具的使用 (55)
- 脚本 (7)
- 汇编 (62)
- 数据结构 (2)
- 财务 (38)
- 语文作文 (16)
- 法律 (1)
- 股票 (88)
最新评论
-
devwang_com:
可以,学习了~~
列出文件夹下所有文件夹的树形结构--Dos命令 tree的使用 -
hvang1988:
不管用啊 frxrprt1.PreviewForm.Pare ...
fastReport预览时嵌入到别的窗体 -
00915132:
我也有这个疑问,非常 感 谢
left join加上where条件的困惑 --SQL优化 -
zhuyoulong:
学习了,高效读书
软件架构师要读的书 -
nTalgar:
非常感谢分享!
Application.ProcessMessages用法:
注意:http://blog.csdn.net/shenyuangong/archive/2008/08/23/2819517.aspx
注:IEnumerable接口有一个方法GetEnumerator。该方法返回一个IEnumerator对象。该对象支持枚举对象方法包括MoveNext() 和Reset(). 另外还有一个Current属性。但是该属性开始的时候指向序列的第一个对象之前。必须用MoveNext()方法移到第一个位置。
-------------------------------------------------------------------
转自:http://hi.baidu.com/l496501043/blog/item/4c69df809abfe9b46d8119c8.html
一、示例:
在C#中,凡是实现了IEnumerator接口的数据类型都可以用foreach语句进行迭代访问,可是,对于自定义类型如何实现这个接口以支持foreach的迭代呢?
* 要实现这个功能,先来看看IEnumerable和IEnumerator接口的定义:
public interface IEnumerable
{
//IEnumerable只有一个方法,返回可循环访问集合的枚举数。
IEnumerator GetEnumerator() ;
}
public interface IEnumerator
{
// 方法
//移到集合的下一个元素。如果成功则返回为 true;如果超过集合结尾,则返回false。
bool MoveNext();
// 将集合设置为初始位置,该位置位于集合中第一个元素之前
void Reset();
// 属性:获取集合中的当前元素
object Current { get; }
}
namespace IEnumberableTest
{
class Program
{
static void Main(string[] args)
{
myEnum enum1 = new myEnum(20);
foreach (point p in enum1)
{
Console.WriteLine("(" + p.x.ToString() + "," + p.y.ToString() + "," + p.z.ToString() + ")");
}
Console.Read();
}
}
//一个结构体,用于类myEnum
struct point
{
public int x;
public int y;
public int z;
}
//一个派生于IEnumerable和IEnumerator接口的自定义类
class myEnum : IEnumerable, IEnumerator
{
//定义索引
private int index;
//定义一个point结构的数组
private point[] points;
//类的构造函数,用于初始化point结构数组
public myEnum(int numofpoint)
{
this.index = -1;
points = new point[numofpoint];
for (int i = 0; i < points.Length; i++)
{
points[i].x = i;
points[i].y = i * i;
points[i].z = i * i * i;
}
}
//实现IEnumerable接口的GetEnumerator方法,返回一个IEnumerator,这里返回我们的自定义类,因为要对这个类的对象进行迭代
public IEnumerator GetEnumerator()
{
return (IEnumerator)this;
}
//实现IEnumerator接口的Reset方法,将集合索引置于第一个元素之前
public void Reset()
{
index = -1;
}
//实现IEnumerator接口的Current属性,返回一个自定义的point结构,即point数组的第index元素
public object Current
{
get
{
return points[index];
}
}
//实现IEnumerator接口的MoveNext方法,用于向前访问集合元素,如果超出集合范围,返回false
public bool MoveNext()
{
index++;
return index >= points.Length ? false : true;
}
}
}
二、区别:
IEnumerable和IEnumerator有什么区别?这是一个很让人困惑的问题(在很多forum里都看到有人在问这个问题)。研究了半天,得到以下几点认识:
1、一个Collection要支持foreach方式的遍历,必须实现IEnumerable接口(亦即,必须以某种方式返回IEnumerator object)。
2、IEnumerator object具体实现了iterator(通过MoveNext(),Reset(),Current)。
3、从这两个接口的用词选择上,也可以看出其不同:IEnumerable是一个声明式的接口,声明实现该接口的class是“可枚举(enumerable)”的,但并没有说明如何实现枚举器(iterator);IEnumerator是一个实现式的接口,IEnumerator object就是一个iterator。
4、IEnumerable和IEnumerator通过IEnumerable的GetEnumerator()方法建立了连接,client可以通过IEnumerable的GetEnumerator()得到IEnumerator object,在这个意义上,将GetEnumerator()看作IEnumerator object的factory method也未尝不可。
IEnumerator 是所有枚举数的基接口。
枚举数只允许读取集合中的数据。枚举数无法用于修改基础集合。
最初,枚举数被定位于集合中第一个元素的前面。Reset 也将枚举数返回到此位置。在此位置,调用 Current 会引发异常。因此,在读取 Current 的值之前,必须调用 MoveNext 将枚举数提前到集合的第一个元素。
在调用 MoveNext 或 Reset 之前,Current 返回同一对象。MoveNext 将 Current 设置为下一个元素。
在传递到集合的末尾之后,枚举数放在集合中最后一个元素后面,且调用 MoveNext 会返回 false。如果最后一次调用 MoveNext 返回 false,则调用 Current 会引发异常。若要再次将 Current 设置为集合的第一个元素,可以调用 Reset,然后再调用 MoveNext。
只要集合保持不变,枚举数就将保持有效。如果对集合进行了更改(例如添加、修改或删除元素),则该枚举数将失效且不可恢复,并且下一次对 MoveNext 或 Reset 的调用将引发 InvalidOperationException。如果在 MoveNext 和 Current 之间修改集合,那么即使枚举数已经无效,Current 也将返回它所设置成的元素。
枚举数没有对集合的独占访问权;因此,枚举一个集合在本质上不是一个线程安全的过程。甚至在对集合进行同步处理时,其他线程仍可以修改该集合,这会导致枚举数引发异常。若要在枚举过程中保证线程安全,可以在整个枚举过程中锁定集合,或者捕捉由于其他线程进行的更改而引发的异常。
发表评论
-
关于 字符串中的单引号, 在sql存储过程中的传输总结; 逗号分隔的多个变量提取方法.
2011-10-14 17:49 3402摘自:http://blog.csdn.net/nutia ... -
抓取网站内容 asp.net
2011-10-11 13:28 1051HttpWebRequest myReq ... -
两个DATASET合并成一个新的DATASET
2011-09-28 18:17 2524摘自:http://topic.csdn.net/t/2 ... -
VS设置使用哪个浏览器来调试网页
2011-08-30 16:57 1197摘自:http://zhidao.baidu.com/ques ... -
可使用js获取TREE的CheckBox
2011-08-20 12:32 1092摘自:http://www.uipower.com/bb ... -
正则表达式 验证邮箱
2011-06-02 18:14 2646正则表达式 摘自:http://www.alixixi.com ... -
未能加载程序集 App_Web_vdcnimdz”错误
2011-04-25 17:38 1599问题描述: 自己的一个WebGPS程序,只是拷到了别的 ... -
.net跳到指定错误页面兵显示详细的错误信息
2011-04-14 16:48 1256.net跳到指定错误页面兵显示详细的错误信息 摘自:h ... -
注册*.ocx控件
2011-04-14 11:23 946注册*.ocx控件 问题描述:本地的网站的bin目录下有了个 ... -
C# 读取文本文件的时候出现汉字乱码
2011-04-12 16:01 2470问题描述:C# 使用ReadAllText方法读取文本文件的时 ... -
VS 2008中如何显示代码的行号
2011-04-09 09:51 1246摘自:http://zhidao.baidu.com/ques ... -
VS.NET2008可以使用书签的功能
2011-04-08 17:19 1392摘自:http://blog.csdn.net/lmh_851 ... -
两个类库要添加引用才能使用
2011-04-02 13:57 1164两个类库要添加引用才能使用 ---------------- ... -
缓存 <%@ OutputCache Duration="6000" VaryByParam="none" %>
2011-04-02 10:53 1179在页首添加: <%@ OutputCache Durat ... -
FrameSet的加载顺序
2011-04-02 09:56 3905FrameSet的加载顺序是: (1) mainFrame ... -
Response.AddHeader “P3P”,”CP=CAO PSA OUR”
2011-04-01 18:01 2549摘自:http://my.donews.com/alor ... -
Hashtable 的使用
2011-03-31 09:36 8182011-3-31 Hashtable 的使用: ... -
google地图使用(二)
2011-03-30 10:30 13312011-3-291. 今天客户反映,说GOOGLE地图上的拖 ... -
GOOGLE地图
2011-03-29 18:31 8332011-3-291. 今天客户反映,说GOOGLE地图上的拖 ... -
此组中没有可用的控件 工具箱 vs2008
2011-03-29 09:20 2134问题描述: 此组中没有可用的控件 工具箱 vs2008 ...
相关推荐
Foreach常用于循环访问集合,对实现IEnumerable的接口的容器进行遍历,IEnumerable和IEnumerator接口我有时候也有点迷糊,按官方的解释,IEnumerable是枚举器接口,IEnumerator是迭代器接口,从字面意思来看相差不大...
### C#自建类实现集合接口 `IEnumerable` 和 `IEnumerator` 在C#中,自定义一个集合类并使其能够支持常见的集合操作(如迭代、添加、删除等)是非常实用的功能。下面将详细介绍如何通过实现 `IEnumerable` 和 `...
当需要遍历集合或自定义数据流时,可以使用IEnumerable接口和IEnumerator接口。这两个接口提供了遍历数据集的能力。 1. 让类继承`IEnumerable<T>`或`IEnumerable`接口,这样你的类就成为了可迭代的对象。这将强制你...
我们经常使用的大多数集合实际上都已经实现了枚举的接口IEnumerable和IEnumerator接口,这样才能使用foreach迭代,有些是含有某种抽象了枚举细节的接口:ArrayList类型有索引,BitArray有Get方法,哈希表和字典有键...
如果该类型是一个泛型集合,还可能需要实现IEnumerable和IEnumerator接口以支持类型安全的枚举。 具体到代码实现,我们可以参考文章中给出的Person类的示例。Person类包含一个字符串数组_names,如果我们希望...
此外,尽管使用IEnumerable和IEnumerator接口可以实现枚举,但这种方式存在性能和类型安全问题。当Current返回object类型时,对于值类型的数据需要进行装箱和拆箱,大量操作时会影响效率。同时,由于返回的是object...
IEnumerator接口包含三个方法:`MoveNext()`、`Reset()`和`Current`属性。 - `MoveNext()`:这个方法将枚举器向前移动到集合中的下一个元素。如果已到达集合的末尾,`MoveNext()`将返回`false`。 - `Reset()`:此...
在C#中,`IEnumerable`和`IEnumerator`接口被用来支持集合的遍历。通过实现这些接口,可以创建可枚举的集合。 ##### 1. `IEnumerable`接口 - **定义**:`IEnumerable`接口用于声明一个集合是可枚举的。这意味着...
`IEnumerator<T>`接口提供了`MoveNext()`、`Reset()`和`Current`属性,用于控制遍历过程和访问当前元素。`IEnumerable<T>`和`IEnumerable`接口的区别在于前者是泛型,后者是为非泛型集合设计的,但两者都支持`...
要使一个类支持foreach遍历,需要实现IEnumerable和IEnumerator接口。这些接口提供了遍历集合的机制。可以通过实现GetEnumerator方法和MoveNext、Reset等方法来实现遍历。 7. 程序中有什么错? 在静态函数中只能...
一、实现foreach的关键: 必须为包含有GetEnumerator()...四、如果返回类型为IEnumerator编译时会实现一个实现了IEnumerator接口的类 五、同理如果返回类型为IEnumerable编译时会实现一个实现了IEnumerable接口的类
- **集合接口使用** - 使用`List<T>`集合来存储水果对象。 - 实现`IEnumerable`接口,并重写`GetEnumerator()`方法。 - `GetEnumerator()`方法返回一个实现了`IEnumerator`接口的枚举器对象,用于迭代集合中的...
本篇文章将深入探讨如何通过自定义类型实现四个关键的系统接口:`IComparable`、`IComparer`、`IEnumerable`和`IEnumerator`以及`IDisposable`。这些接口在各种场景下都有广泛的应用,例如数据排序、枚举遍历和资源...
总的来说,`IEnumerable`接口和`IEnumerator`接口是C#中实现迭代的关键,它们使得开发者能够方便地遍历任何可枚举类型的集合,包括自定义的集合类型。在给定的例子中,通过自定义迭代器,我们能够以反向顺序遍历字符...
C#中的迭代器封装在IEnumerable和IEnumerator和他们的泛型接口中。 IEnumerable:定义了一个可以获取IEnumerator的方法—GetEnumerator()。 //IEnumerable的代码实现 public interface IEnumerable { ...
本文将深入解析C#中的一些关键非泛型集合接口,如`IEnumerable`、`IEnumerator`、`IComparer`、`IEqualityComparer`、`IStructuralComparable`、`IStructuralEquatable`、`ICollection`、`IList`以及`IDictionary`...
.NET中存在两种类型的枚举器:非泛型的`IEnumerator/IEnumerable`接口和泛型的`IEnumerator<T>/IEnumerable<T>`接口。非泛型版本可以返回任何类型的元素,但可能导致类型转换的开销,而泛型版本则提供了类型安全的...