Enumerable和IEnumerator接口是.NET中非常重要的接口,二者区别:

1. IEnumerable是个声明式的接口,声明实现该接口的类就是“可迭代的enumerable”,但并没用说明如何实现迭代器(iterator).其代码实现为:

public interface IEnumerable
     {
          IEnumerator GetEnumerator();
     }
2. IEnumerator是个实现式接口,它声明实现该接口的类就可以作为一个迭代器iterator.其代码实现为:

public interface IEnumerator
    {
         object Current { get; }

bool MoveNext();
         void Reset();
    }

3.一个collections要支持Foreach进行遍历,就必须实现IEnumerable,并一某种方式返回迭代器对象:IEnumerator.

static void Main(string[] args)
{
  #region ICollection(CopyTo方法) IEnumerator(支持所有一般非泛型集合) IDictionaryEnuerator(HashTable/SortList支持一般非泛型键值对集合)

  //集群枚举器:可以概念上认为复制了原始集群中的内容

  Console.WriteLine("------------ 1 ArrayList-----------------");

  #region ArrayList:IEnumerator

  ArrayList al = new ArrayList() { 1, 2, 3, 4 };
  IEnumerator iEnum = al.GetEnumerator();

  IEnumerable alIEnumerable = (IEnumerable)al.GetEnumerator();
  foreach (var item in alIEnumerable)
  {
    Console.WriteLine(string.Format("IEnumerable{0} = {1}",item.ToString(),item.ToString()));
  }

  while (iEnum.MoveNext())
  {
    Console.WriteLine(string.Format("IEnumerator{0} = {1}",iEnum.Current,iEnum.Current));
  }

  #endregion

  Console.WriteLine();
  Console.WriteLine("------------ 2 SortedList-----------------");

  #region SortedList:IEnumerator/IDictionaryEnumerator

  SortedList sl = new SortedList();
  sl.Add(1, 1);
  sl.Add(2, 2);
  sl.Add(3, 3);
  IEnumerator slIEnum = sl.GetEnumerator();
  while (slIEnum.MoveNext())
  {
    DictionaryEntry slDE = (DictionaryEntry)slIEnum.Current;
    Console.WriteLine(string.Format("slIEnum{0} = {1}", slDE.Key, slDE.Value));
  }

  Console.WriteLine("-------------------------------------");

  IDictionaryEnumerator slIDicEnum = sl.GetEnumerator();
  while (slIDicEnum.MoveNext())
  {
    Console.WriteLine(string.Format("slIDicEnum{0} = {1}", slIDicEnum.Key, slIDicEnum.Value));
  }

  #endregion

  Console.WriteLine();
  Console.WriteLine("------------ 3 Hashtable-----------------");

  #region Hashtable:IEnumerator/IDictionaryEnumerator

  Hashtable ht = new Hashtable();
  ht.Add(1,1);
  ht.Add(2,2);
  ht.Add(3, 3);
  IEnumerator htIEnum = ht.GetEnumerator();
  while (htIEnum.MoveNext())
  {
    DictionaryEntry de = (DictionaryEntry)htIEnum.Current;

    Console.WriteLine(string.Format("htKeyIEnum{0} = {1},htValueIEnum{2} = {3}", de.Key, de.Key, de.Value, de.Value));
  }

  Console.WriteLine("-------------------------------------");

  IDictionaryEnumerator htIDicEnum = ht.GetEnumerator();
  while (htIDicEnum.MoveNext())
  {
    Console.WriteLine(string.Format("htIDicEnumKey{0} = {1},htIDicEnumValue{2} = {3}", htIDicEnum.Key, htIDicEnum.Key, htIDicEnum.Value,     htIDicEnum.Value));
  }

  #endregion

  Console.WriteLine();
  Console.WriteLine("------------ 4 ICollection---------------");

  #region ICollection:从指定的System.Array索引处,将System.Collections.ICollection的元素复制到System.Array中

  ICollection icKey = ht.Keys;
  ICollection icValue = ht.Values;

  int[] intKey = new int[icKey.Count];
  int[] intValue = new int[icValue.Count];

  //从指定的System.Array索引处,将System.Collections.ICollection的元素复制到System.Array中
  icKey.CopyTo(intKey, 0);
  icValue.CopyTo(intValue, 0);

  foreach (int i in intKey)
  {
    Console.WriteLine(string.Format("intKey[{0}]= {1}", i, i));
  }

  Console.WriteLine("-------------------------------------");

  foreach (int i in icValue)
  {
    Console.WriteLine(string.Format("intValue[{0}]= {1}", i, i));
  }

  #endregion

  #region IEnumerable

  foreach (int i in ShowIEnumerable(2, 8))
  {
    Console.WriteLine(i);
  }

  #endregion

  #endregion

  Console.ReadKey();
}

/// <summary>
/// yield:在迭代器块中用于向枚举数对象提供值或发出迭代结束信号。
/// 它的形式为下列之一:
/// 1)yield return <expression>;
/// 2)yield break;
/// 计算表达式并以枚举数对象值的形式返回;expression 必须可以隐式转换为迭代器的 yield 类型。
/// yield 语句只能出现在 iterator 块中,该块可用作方法、运算符或访问器的体。这类方法、运算符或访问器的体受以下约束的控制:
/// 1)不允许不安全块。
/// 2)方法、运算符或访问器的参数不能是 ref 或 out
/// 此外:
/// 1)yield 语句不能出现在匿名方法中
/// 2)当和 expression 一起使用时,yield return 语句不能出现在 catch 块中或含有一个或多个 catch 子句的 try 块中
/// </summary>
/// <param name="num1"></param>
/// <param name="num2"></param>
/// <returns></returns>

public static IEnumerable ShowIEnumerable(int num1, int num2)
{
  int num3 = 0;
  int result = 1;
  while (num3++ < num2)
  {
    result = result * num1;
    yield return result;
  }
}

ICollection IEnumerable/IEnumerator IDictionaryEnumerator yield的更多相关文章

  1. C#中的 IList, ICollection ,IEnumerable 和 IEnumerator

    IList, ICollection ,IEnumerable 很显然,这些都是集合接口的定义,先看看定义: // 摘要: // 表示可按照索引单独访问的对象的非泛型集合. [ComVisible(t ...

  2. IList, ICollection ,IEnumerable AND IEnumerator in C#

    IList, ICollection ,IEnumerable 很显然,这些都是集合接口的定义,先看看定义: // 摘要: // 表示可按照索引单独访问的对象的非泛型集合. [ComVisible(t ...

  3. C# ~ 从 IEnumerable / IEnumerator 到 IEnumerable<T> / IEnumerator<T> 到 yield

    IEnumerable / IEnumerator 首先,IEnumerable / IEnumerator 接口定义如下: public interface IEnumerable /// 可枚举接 ...

  4. IEnumerable、IEnumerator与yield的学习

    我们知道数组对象可以使用foreach迭代进行遍历,同时我们发现类ArrayList和List也可以使用foreach进行迭代.如果我们自己编写的类也需要使用foreach进行迭代时该怎么办呢? IE ...

  5. IEnumerable, IEnumerator接口

    IEnumerable接口 // Exposes the enumerator, which supports a simple iteration over a non-generic collec ...

  6. [原译]实现IEnumerable接口&理解yield关键字

    原文:[原译]实现IEnumerable接口&理解yield关键字 著作权声明:本文由http://leaver.me 翻译,欢迎转载分享.请尊重作者劳动,转载时保留该声明和作者博客链接,谢谢 ...

  7. c#yield,IEnumerable,IEnumerator

    foreach 在编译成IL后,实际代码如下: 即:foreach实际上是先调用可枚举对象的GetEnumerator方法,得到一个Enumerator对象,然后对Enumerator进行while循 ...

  8. 【Unity|C#】基础篇(20)——枚举器与迭代器(IEnumerable/IEnumerator)

    [学习资料] <C#图解教程>(第18章):https://www.cnblogs.com/moonache/p/7687551.html 电子书下载:https://pan.baidu. ...

  9. IEnumerable & IEnumerator

    IEnumerable 只有一个方法:IEnumerator GetEnumerator(). INumerable 是集合应该实现的一个接口,这样,就能用 foreach 来遍历这个集合. IEnu ...

随机推荐

  1. redis分布式锁-基本概念与实现方式对比

    1.redis中使用WATCH实现锁机制,是最次之的方式.WATCH只会在数据被其他客户端抢先修改了的情况下,“通知”执行了这个命令的客户端,而不会阻止其他客户端对数据进行修改.此类锁成为“乐观锁” ...

  2. vue 引入 fontawesome 报错 Could not find one or more icon(s) 解决

    在 vue 项目中引用 fontawesome , 按照官方说明如下步骤操作 1. 终端中执行 $ npm i --save @fortawesome/fontawesome-svg-core $ n ...

  3. dede tag标签静态化

    看回那2个文件夹即可,txt说明书我已经修改过. 下面说一下tag标签静态化之后在内容页.列表页中如何使用. 内容页中沿用之前的方法即可: {dede:tag sort='new' getall='0 ...

  4. 前端防止url输入地址直接访问页面

    首先,解决这个问题要搞明白此url是从程序内部跳转还是直接在地址栏输入的,如果是程序内部跳转,那就好办啦.方法如下: 判断用户是否登录状态,是否携带token 使用router.beforeEach注 ...

  5. 【maven的使用】2使用maven与pom文件

    一.使用maven:首先需要知道的是,在我们开发人员中有一句话叫做:约定优于配置.比如,如果我们写代码有多种可选方案:硬编码形式:obj.setPath("d:/xxxx") .配 ...

  6. linux分析工具之lsof详解

    一.概述 在linux中,所有东西都是以文件的形式存在的,所以我们在linux上的操作都是通过对文件的操作来执行我们所需要的逻辑,比如我们对文件数据的访问,修改,访问网络的连接等,刚好lsof(lis ...

  7. 超详细!! sql server 同步数据库 发布 订阅 跨网段 无公网ip 常见问题

    问题描述 主机1:发布端 阿里云服务器--有公网ip 主机2:订阅端 笔记本--无公网ip 数据量很小,主要是熟悉发布订阅的操作流程. 主机2仅仅作为主机1的本地备份,要求修改云服务器上数据后,能通过 ...

  8. POJ - 2393Yogurt factory

    The cows have purchased a yogurt factory that makes world-famous Yucky Yogurt. Over the next N (1 &l ...

  9. COGS 2095. 不平凡的引线

    2095. 不平凡的引线 ★☆   输入文件:firelead.in   输出文件:firelead.out   简单对比 时间限制:1 s   内存限制:256 MB [题目描述] 这里说的引线是炮 ...

  10. 想转行做3D游戏模型,如何快速入行

    随着技术和硬件迭代,3D建模,广泛运用在游戏,影视,动画,VR等领域,而且就业面非常广. 由于3D美术设计师薪资和前景确实都不错,很多同学想进入这个行业,从事相关工作,但是没有一个整体的学习思路和规划 ...