C# 9 新特性 —— 增强的 foreach

Intro

在 C# 9 中增强了 foreach 的使用,使得一切对象都有 foreach 的可能

我们来看一段代码,这里我们试图遍历一个 int 类型的值

思考一下,我们可以怎么做使得上面的代码编译通过呢?

迭代器模式

迭代器模式,提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露该对象的内部表示。

迭代器模式是分离了集合对象的遍历行为,抽象出一个迭代器类来负责,这样既可以做到不暴露集合的内部结构,又可以让外部代码透明地访问集合内部的数据。

foreach 其实是一个迭代器模式的语法糖,用来遍历一个集合中的数据,foreach 可以使用 while 来实现,比如下面这个示例:

var enumerable = Enumerable.Range(1, 10).ToArray();
foreach (var i in enumerable)
{
Console.WriteLine(i);
}

使用 while 重写之后类似下面这样的代码:

var enumerator = enumerable.GetEnumerator();
while (enumerator.MoveNext())
{
Console.WriteLine(enumerator.Current);
}

c# 中的集合基本都实现了迭代器模式,可以直接使用 foreach 来遍历,对于自定义的类型想要支持 foreach 可以实现 IEnumerableIEnumerable<T>,对于没有实现迭代器的代码,是不是可以用 foreach

Enumerator

我们再来看开篇提到的问题,怎么实现支持 foreach

从上面 VS 的提示我们可以看得出来,如果一个类型想要支持 foreach,有三种方式可以实现:

  1. 实现 IEnumerable
  2. 实现 IEnmuerable<T>
  3. 添加 GetEnumerator 方法,方法返回值类型需要有 Current 属性和 MoveNext 方法,可以参考这个 IEnumerator,返回类型可以直接实现 IEnumeratorIEnumerator<T>

那么如果是一个别人封装的类型,能否支持 foreach 呢,从 C# 9 之后就可以了,可以添加一个 GetEnumerator 的扩展方法,类似于下面

public static class ForEachExtensions
{
public static IEnumerator<char> GetEnumerator(this int num)
{
return num.ToString().GetEnumerator();
}
}

此时如果是使用 C# 9 就可以编译通过了,如果手动设置了 LangVersion,需要修改为 9,否则会得到类似下面这样的错误

添加使用扩展方法,并启用 C# 9 语法:

More

有了这个功能之后,一切类型都是可以 foreach 的,没有实现迭代器模式的类型,只需要实现一个扩展方法就可以了

迎接 C# 9 ,万物皆可 foreach ~~

Reference

C# 9 新特性 —— 增强的 foreach的更多相关文章

  1. 使用 HTML5 History 新特性增强 Ajax 的体验(转)

    一. 场景再现 如大家熟知,Ajax 可以实现页面的无刷新操作,但会造成两个与普通页面操作(有刷新地改变页面)有着明显差别的问题—— URL 没有修改以及无法使用前进.后退按钮.例如常见的 Ajax ...

  2. C# 9 新特性 —— 增强的模式匹配

    C# 9 新特性 -- 增强的模式匹配 Intro C# 9 中进一步增强了模式匹配的用法,使得模式匹配更为强大,我们一起来了解一下吧 Sample C# 9 中增强了模式匹配的用法,增加了 and/ ...

  3. jdk1.5出现的新特性---->增强for循环

    import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.Map; ...

  4. Java12新特性 -- 增强G1,自动返回未用堆内存给操作系统

    Java 12 中增强了 G1 垃圾收集器关于混合收集集合的处理策略,这节主要介绍在 Java 12 中同时也对 G1垃圾回收器进行了改进,使其能够在空闲时自动将 Java 堆内存返还给操作系统,这也 ...

  5. Java JDK5新特性-增强for

    2017-10-31 00:02:16 格式: for(元素数据类型 变量:数组或者Collection集合) { 使用变量即可,该变量即是元素 } int arr[] = {1,2,3,4,5}; ...

  6. C# 6.0/7.0 的新特性

    转眼C#语言都已经迭代到7.0版本了,很多小伙伴都已经把C# 7.0 的新特性应用到代码中了,想想自己连6.0的新特性都还很少使用,今天特意搜集了一下6.0和7.0的一些新特性,记录一下,方便查阅. ...

  7. JDK5的新特性之 增强for

      package cn.itcast.day19.foreach; import java.util.ArrayList; import java.util.Collection; import j ...

  8. Oracle 11g新特性延迟段创建和truncate的增强

    下面测试Oracle 11g开始的新特性truncate的增强和延迟段空间创建. Oracle从11g开始,当用户创建一张空表的时候不会先分配段和空间,只有当对这张表插入第一行数据的时候才分配段和空间 ...

  9. Spring4.1新特性——Spring缓存框架增强(转)

    目录 Spring4.1新特性——综述 Spring4.1新特性——Spring核心部分及其他 Spring4.1新特性——Spring缓存框架增强 Spring4.1新特性——异步调用和事件机制的异 ...

随机推荐

  1. linux上的PXE装机服务的搭建

    PXE 先安装一下依赖服务 yum -y install vsftpd dhcp tftp syslinux tftp-server cd /var/ftp/pub/ mkdir dvd 设置权限 c ...

  2. JavaScript的执行上下文,真没你想的那么难

    作者:小土豆 博客园:https://www.cnblogs.com/HouJiao/ 掘金:https://juejin.im/user/2436173500265335 前言 在正文开始前,先来看 ...

  3. [从源码学设计]蚂蚁金服SOFARegistry之消息总线

    [从源码学设计]蚂蚁金服SOFARegistry之消息总线 目录 [从源码学设计]蚂蚁金服SOFARegistry之消息总线 0x00 摘要 0x01 相关概念 1.1 事件驱动模型 1.1.1 概念 ...

  4. web.xml之servlet与filter配置

    servlet配置 一个完整的servlet配置分为两块,< servlet >块和< servlet-mapping >块 < servlet > <ser ...

  5. LeetCode 048 Rotate Image

    题目要求:Rotate Image You are given an n x n 2D matrix representing an image. Rotate the image by 90 deg ...

  6. MongoTemplate 移除 _class 字段

    @Configuration public class ApplicationReadyListener implements ApplicationListener<ContextRefres ...

  7. PyQt(Python+Qt)学习随笔:QTableWidgetItem项的复选状态checkState访问方法

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 QTableWidget表格部件中的QTableWidgetItem项可以单独设置复选状态,如图所有 ...

  8. PyQt(Python+Qt)学习随笔:Qt Designer中部件的焦点策略focusPolicy设置

    在Qt Designer中可以设置部件的焦点策略,部件的焦点策略属性取值范围由枚举类型Qt.FocusPolicy来定义,该枚举类型及其含义如下表所示: 注意:经老猿测试鼠标轮滚动获取焦点,只有在鼠标 ...

  9. [GXYCTF2019] MISC杂项题

    buuoj复现 1,佛系青年 下载了之后是一个加密的txt文件和一张图片 分析图片无果,很讨厌这种脑洞题,MISC应该给一点正常的线索加部分脑洞而不是出干扰信息来故意让选手走错方向,当时比赛做这道题的 ...

  10. 效率神器-uTools推荐和使用

    提高办公开发效率...非常好用  功能很多很全,官网:https://u.tools/ 文档:https://u.tools/docs/guide/about-uTools.html