惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Help Net Security
Help Net Security
G
Google Developers Blog
雷峰网
雷峰网
WordPress大学
WordPress大学
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Engineering at Meta
Engineering at Meta
Security Latest
Security Latest
T
Threat Research - Cisco Blogs
AWS News Blog
AWS News Blog
F
Full Disclosure
C
Cybersecurity and Infrastructure Security Agency CISA
T
The Exploit Database - CXSecurity.com
J
Java Code Geeks
U
Unit 42
C
Cyber Attacks, Cyber Crime and Cyber Security
V
V2EX
C
Cisco Blogs
博客园 - 司徒正美
Project Zero
Project Zero
L
LINUX DO - 热门话题
阮一峰的网络日志
阮一峰的网络日志
Blog — PlanetScale
Blog — PlanetScale
Scott Helme
Scott Helme
A
About on SuperTechFans
Hugging Face - Blog
Hugging Face - Blog
S
Securelist
小众软件
小众软件
aimingoo的专栏
aimingoo的专栏
S
Schneier on Security
G
GRAHAM CLULEY
酷 壳 – CoolShell
酷 壳 – CoolShell
Cyberwarzone
Cyberwarzone
MongoDB | Blog
MongoDB | Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园 - 叶小钗
T
Threatpost
Recorded Future
Recorded Future
C
CXSECURITY Database RSS Feed - CXSecurity.com
宝玉的分享
宝玉的分享
N
News and Events Feed by Topic
人人都是产品经理
人人都是产品经理
The Register - Security
The Register - Security
S
Security Archives - TechRepublic
博客园 - Franky
N
News | PayPal Newsroom
Simon Willison's Weblog
Simon Willison's Weblog
S
SegmentFault 最新的问题
W
WeLiveSecurity
A
Arctic Wolf
B
Blog

博客园 - 马啸西风

SQL Server 2008之XML数据存储 SQL Server 2008之托管代码 SQL Server 2008之触发器 SQL Server 2008之约束 SQL Server 2008之用户自定义函数 SQL Server 2008之错误处理 SQL Server 2008之创建高并发应用程序 SQL Server 2008之合并数据和表传递 SQL Server 2008之存储过程的设计和实现 SQL Server 2008之通过非聚集索引提高性能 SQL Server 2008之读取查询计划 SQL Server 2008之表结构实现 SQL Server 2008之索引设计 SQL Server 2008之视图的设计和实现 SQL Server 2008之表的设计和实现 SQL Server 2008之数据类型 启用Application library caching时,将多个不同步的程序集打包到一个ZIP包中的问题 垃圾收集导致的概率性发生的bug DataGridView中下拉列表框的实现
C#之集合
马啸西风 · 2011-01-25 · via 博客园 - 马啸西风

  C#的集合功能可谓十分强大,这里着重探讨集合中非常重要的两个接口:IEnumerable<T>和IEnumerator<T>.

  首先查看如下代码:

代码

 1  class Student
 2     {
 3         public int _id;
 4         public string _name;
 5 
 6         public Student(int id, string name)
 7         {
 8             this._id = id;
 9             this._name = name;
10         }
11 
12         public override string ToString()
13         {
14             return string.Format("{0}-{1}", _id, _name);
15         }
16     }
17 
18     class Program
19     {
20         public static void Main()
21         {
22             List<Student> students = new List<Student>()
23             {
24                 new Student(1"Tomas"), new Student(2"Lily")
25             };
26 
27             foreach (Student student in students)
28             {
29                 Console.WriteLine(student);
30             }
31         }
32     }

这里我首先定义一个学生类,然后在Main方法中定义一个集合, 这里用集合初始化器向集合中添加内容,最后在遍历集合中的内容。我们看到C#中遍历集合的内容是如此方便。可以说C#中对如何访问集合内的元素进行彻底的封装,我们不必了解集合内部的结构,就能轻松访问集合的内容,然后借助查询表达式或者查询运算符可以进行查询等一系列方便的操作,这里不再赘述。

  但是C#内部究竟是怎么访问集合中的数据的呢?这就要提到我们上面提到的接口IEnumerable<T> ,所有集合都实现了该接口,或者更精确的说所有想要被foreach遍历的集合必须实现这个接口。这个接口十分简单,实现该接口的类只要实现GetEnumerator()方法就可以了。如下所示:

代码

 1     [TypeDependency("System.SZArrayHelper")]
 2     public interface IEnumerable<out T> : IEnumerable
 3     {
 4         IEnumerator<T> GetEnumerator();
 5     }

这里就有涉及到我提到的另一个接口IEnumerator<T>,那这个接口又是干什么的呢?使用java的人都知道java中遍历集合通常使用Iterator,也就是迭代器,你可以在不知道集合内部结构的前提下,轻松访问集合的数据,也就是设计模式中的迭代器模式。C#中IEnumerator就是迭代器,其内部结构如下所示:

代码

 1     [ComVisible(true)]
 2     [Guid("496B0ABF-CDEE-11d3-88E8-00902754C43A")]
 3     public interface IEnumerator
 4     {
 5         object Current { get; }
 6 
 7         bool MoveNext();
 8 
 9         void Reset();
10     }

IEnumerator接口的Current属性用于获取当前对象,MoveNext()则告诉调用者是否还有下一个元素。

我们回到本文的第一个代码,当我们遍历集合的时候,由于该集合实现了IEnumerable<T>接口,所以foreach会调用IEnumerable的GetEnumerator()方法,返回一个迭代器对象,然后利用迭代器就可以访问集合中的数据了,当然所有这一切都是隐式调用的。如下所示:

1      IEnumerator<Student> enumerator = new new List<Student>.Enumerator();
2 
3      while (enumerator.MoveNext())
4      {
5        Console.WriteLine(enumerator.Current);
6      }

在java中是不是就是这样访问集合元素的啊。