IEnumerable<T> 接口和GetEnumerator 详解
IEnumerable<T> 接口
公开枚举数,该枚举数支持在指定类型的集合上进行简单迭代。
若要浏览此类型的.NET Framework 源代码,请参阅参考源。
命名空间: System.Collections.Generic
程序集: mscorlib(在 mscorlib.dll 中)
public interface IEnumerable<out T> : IEnumerable
类型参数
- out T
-
要枚举的对象的类型。
此类型参数是协变。即可以使用指定的类型或派生程度更高的类型。有关协变和逆变的详细信息,请参阅 泛型中的协变和逆变。
IEnumerable<T> 类型公开以下成员。
方法
名称 | 描述 | |
---|---|---|
![]() ![]() ![]() |
GetEnumerator | 返回一个循环访问集合的枚举器。 |
GetEnumerator 详解
返回一个循环访问集合的枚举器。
命名空间: System.Collections.Generic
程序集: mscorlib(mscorlib.dll 中)
语法
IEnumerator<T> GetEnumerator()
返回IEnumerator<T>提供了通过公开来循环访问集合的能力Current属性。读取集合中的数据,但不是能修改集合,您可以使用枚举器。
最初,枚举数位于集合中的第一个元素之前。在此位置上,Current是不确定的。因此,您必须调用MoveNext方法使枚举器前进到之前读取值的集合的第一个元素Current。
Current返回同一个对象,直到MoveNext作为再次调用MoveNext设置Current到下一个元素。
如果MoveNext越过集合,该枚举数的末尾将被定位在集合中的最后一个元素之后和MoveNext返回false。当枚举数位于此位置上,对后续调用MoveNext也会返回false。如果最后一次调用到MoveNext返回false,Current是不确定的。您不能设置Current再次为集合的第一个元素必须改为创建新的枚举器实例。
一个枚举器没有对集合的独占访问,因此,只要集合保持不变,枚举器保持有效。如果进行了更改到集合中,如添加、 修改,或删除元素),则枚举器将失效,并可能会收到意外的结果时。此外,对集合进行枚举不是线程安全过程。若要保证线程安全,您应枚举期间锁定集合,或实现同步对集合。
集合中的默认实现System.Collections.Generic命名空间时不同步。
using System;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using System.Linq; public class App
{
// Excercise the Iterator and show that it's more
// performant.
public static void Main()
{
TestStreamReaderEnumerable();
Console.WriteLine("---");
TestReadingFile();
} public static void TestStreamReaderEnumerable()
{
// Check the memory before the iterator is used.
long memoryBefore = GC.GetTotalMemory(true);
IEnumerable<String> stringsFound;
// Open a file with the StreamReaderEnumerable and check for a string.
try {
stringsFound =
from line in new StreamReaderEnumerable(@"c:\temp\tempFile.txt")
where line.Contains("string to search for")
select line;
Console.WriteLine("Found: " + stringsFound.Count());
}
catch (FileNotFoundException) {
Console.WriteLine(@"This example requires a file named C:\temp\tempFile.txt.");
return;
} // Check the memory after the iterator and output it to the console.
long memoryAfter = GC.GetTotalMemory(false);
Console.WriteLine("Memory Used With Iterator = \t"
+ string.Format(((memoryAfter - memoryBefore) / ).ToString(), "n") + "kb");
} public static void TestReadingFile()
{
long memoryBefore = GC.GetTotalMemory(true);
StreamReader sr;
try {
sr = File.OpenText("c:\\temp\\tempFile.txt");
}
catch (FileNotFoundException) {
Console.WriteLine(@"This example requires a file named C:\temp\tempFile.txt.");
return;
} // Add the file contents to a generic list of strings.
List<string> fileContents = new List<string>();
while (!sr.EndOfStream) {
fileContents.Add(sr.ReadLine());
} // Check for the string.
var stringsFound =
from line in fileContents
where line.Contains("string to search for")
select line; sr.Close();
Console.WriteLine("Found: " + stringsFound.Count()); // Check the memory after when the iterator is not used, and output it to the console.
long memoryAfter = GC.GetTotalMemory(false);
Console.WriteLine("Memory Used Without Iterator = \t" +
string.Format(((memoryAfter - memoryBefore) / ).ToString(), "n") + "kb");
}
} // A custom class that implements IEnumerable(T). When you implement IEnumerable(T),
// you must also implement IEnumerable and IEnumerator(T).
public class StreamReaderEnumerable : IEnumerable<string>
{
private string _filePath;
public StreamReaderEnumerable(string filePath)
{
_filePath = filePath;
} // Must implement GetEnumerator, which returns a new StreamReaderEnumerator.
public IEnumerator<string> GetEnumerator()
{
return new StreamReaderEnumerator(_filePath);
} // Must also implement IEnumerable.GetEnumerator, but implement as a private method.
private IEnumerator GetEnumerator1()
{
return this.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator1();
}
} // When you implement IEnumerable(T), you must also implement IEnumerator(T),
// which will walk through the contents of the file one line at a time.
// Implementing IEnumerator(T) requires that you implement IEnumerator and IDisposable.
public class StreamReaderEnumerator : IEnumerator<string>
{
private StreamReader _sr;
public StreamReaderEnumerator(string filePath)
{
_sr = new StreamReader(filePath);
} private string _current;
// Implement the IEnumerator(T).Current publicly, but implement
// IEnumerator.Current, which is also required, privately.
public string Current
{ get
{
if (_sr == null || _current == null)
{
throw new InvalidOperationException();
} return _current;
}
} private object Current1
{ get { return this.Current; }
} object IEnumerator.Current
{
get { return Current1; }
} // Implement MoveNext and Reset, which are required by IEnumerator.
public bool MoveNext()
{
_current = _sr.ReadLine();
if (_current == null)
return false;
return true;
} public void Reset()
{
_sr.DiscardBufferedData();
_sr.BaseStream.Seek(, SeekOrigin.Begin);
_current = null;
} // Implement IDisposable, which is also implemented by IEnumerator(T).
private bool disposedValue = false;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
} protected virtual void Dispose(bool disposing)
{
if (!this.disposedValue)
{
if (disposing)
{
// Dispose of managed resources.
}
_current = null;
if (_sr != null) {
_sr.Close();
_sr.Dispose();
}
} this.disposedValue = true;
} ~StreamReaderEnumerator()
{
Dispose(false);
}
}
// This example displays output similar to the following:
// Found: 2
// Memory Used With Iterator = 33kb
// ---
// Found: 2
// Memory Used Without Iterator = 206kb
IEnumerable<T> 接口和GetEnumerator 详解的更多相关文章
- c# WebApi之接口返回类型详解
c# WebApi之接口返回类型详解 https://blog.csdn.net/lwpoor123/article/details/78644998
- “全栈2019”Java第六十四章:接口与静态方法详解
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...
- “全栈2019”Java第六十三章:接口与抽象方法详解
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...
- “全栈2019”Java第六十二章:接口与常量详解
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...
- LWIP network interface 即 LWIP 的 硬件 数据 接口 移植 首先 详解 STM32 以太网数据 到达 的第一站: ETH DMA 中断函数
要 运行 LWIP 不光 要实现 OS 的 一些 接口 ,还要 有 硬件 数据 接口 移植 ,即 网线上 来的 数据 怎么个形式 传递给 LWIP ,去解析 做出相应的 应答 ,2017 ...
- 抽象类和接口的区别详解、package和import
1.抽象类和接口以及抽象类和接口的区别. 1.1.抽象类的基础语法(见昨天笔记) 1.2.接口的基础语法 1.接口是一种"引用数据类型". 2.接口是完全抽象的. 3.接口怎么定义 ...
- Java接口修饰符详解
接口就是提供一种统一的”协议”,而接口中的属性也属于“协议”中的成员.它们是公共的,静态的,最终的常量.相当于全局常量.抽象类是不“完全”的类,相当于是接口和具体类的一个中间层.即满足接口的抽象,也满 ...
- python接口自动化(三)--如何设计接口测试用例(详解)
简介 上篇我们已经介绍了什么是接口测试和接口测试的意义.在开始接口测试之前,我们来想一下,如何进行接口测试的准备工作.或者说,接口测试的流程是什么?有些人就很好奇,接口测试要流程干嘛?不就是拿着接口文 ...
- Spring钩子方法和钩子接口的使用详解
本文转自:http://www.sohu.com/a/166804449_714863 前言 SpringFramework其实具有很高的扩展性,只是很少人喜欢挖掘那些扩展点,而且官方的Refrenc ...
随机推荐
- 焦作网络赛L-Poor God Water【矩阵快速幂】
God Water likes to eat meat, fish and chocolate very much, but unfortunately, the doctor tells him t ...
- Linux自动化部署尝试
Linux自动化部署尝试 最近做一个项目临近测试,购买的是阿里云的服务器,每次部署都是手动打包war,然后上传到服务器,然后修改配置文件,不仅繁琐,而且费时,就思索着找一个一键式的部署方式,今天终 ...
- Python开发【模块】:BeautifulSoup
BeautifulSoup BeautifulSoup是一个模块,该模块用于接收一个HTML或XML字符串,然后将其进行格式化,之后遍可以使用他提供的方法进行快速查找指定元素,从而使得在HTML或XM ...
- Python开发【笔记】:git&github 快速入门
github入门 简介: 很多人都知道,Linus在1991年创建了开源的Linux,从此,Linux系统不断发展,已经成为最大的服务器系统软件了. Linus虽然创建了Linux,但Linux的壮大 ...
- IOS使用Core-Plot画折线图
关于Core-Plot的配置.大家能够參考我的上一篇博客:http://1.wildcat.sinaapp.com/?p=99 版权全部.转载请注明原文转自:http://blog.csdn.net/ ...
- 10行代码搞定移动web端自定义tap事件
发发牢骚 移动web端里摸爬滚打这么久踩了不少坑,有一定移动web端经验的同学一定被click困扰过.我也不列外.一路走来被虐的不行,fastclick.touchend.iscroll什么的都用过, ...
- 国内比特币bitcoin交易平台
火币网: www.huobi.com 比特币中国: www.btcchina.com okcoin: www.okcoin.cn 中国比特币: www.chbtc.com 比特币交易 ...
- DNS服务器配置实践
实验背景:在Linux系统上配置主要DNS服务器和辅助DNS服务器,所在域名为example.com,子网为192.168.X.0. 启动已安装LINUX系统,进行DNS服务器配置. 一.配置主要DN ...
- Mist 转移默认区块存储位置方法
http://8btc.com/thread-35325-1-1.html 看了bunaifeiqq 发的帖子“Mist 转移区块存储位置方法”,综合帖子下面的发言,自己做了测试,可行.电脑系统win ...
- python中 @property
考察 Student 类: class Student(object): def __init__(self, name, score): self.name = name self.score = ...