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 tips

从上面 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

  • https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-9

  • https://github.com/WeihanLi/SamplesInPractice/tree/master/CSharp9Sample

  • https://github.com/WeihanLi/SamplesInPractice/blob/master/CSharp9Sample/ForEachExtensions.cs

C# 9 新特性 —— 增强的 foreach相关推荐

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

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

  2. java for each 的源_Java JDK1.5的新特性之for-each循环的底层原理

    今天给大家分享一下for-each循环的底层原理,故事还得从字节码反汇编和反编译说起... 首先看一下Java JDK1.5的新特性 泛型: ... for-each. ... 自动拆箱和装箱功能 . ...

  3. JDK5的新特性之 增强for

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

  4. java9新特性--jShell--命令语法改进:try语和接口的私有方法--String存储结构变更--集合工厂方法--模块化系统--InputStream 加强--增强的 Stream API

    目录 Java 9 的新特性 JDK 和 JRE 目录结构的改变 模块化系统: Jigsaw -> Modularity 实现目标 模块 结构 jShell命令 产生背景 设计理念 实现目标 j ...

  5. Oracle 11g 新特性 -- Transparent Data Encryption (透明数据加密TDE) 增强 说明

    一.TransparentData Encryption (TDE:透明数据加密) 说明 Orace TDE 是Orcle 10R2中的一个新特性,其可以用来加密数据文件里的数据,保护从操作系统层面上 ...

  6. Spring4新特性——Web开发的增强

    2019独角兽企业重金招聘Python工程师标准>>> Spring4新特性--泛型限定式依赖注入 Spring4新特性--核心容器的其他改进 Spring4新特性--Web开发的增 ...

  7. Java SE 6 新特性: HTTP 增强--转

    概述 Java 语言从诞生的那天起,就非常注重网络编程方面的应用.随着互联网应用的飞速发展,Java 的基础类库也不断地对网络相关的 API 进行加强和扩展.在 Java SE 6 当中,围绕着 HT ...

  8. Oracle12c功能增强 新特性之管理功能的增强

    1.    数据文件在线重命名和迁移 不想先前的版本号.在Oracle12cR1中,数据文件的迁移或重命名不再要求一系列的步骤,比如:将表空间至于仅仅读模式,然后数据文件逻辑等操作.在12cR1中.数 ...

  9. oracle 12c dg新特性,oracle 12c:新特性-网格(Grid)基础架构的增强

    oracle 12c:新特性-网格(Grid)基础架构的增强,传统标准集群和Flex集群. Flex 集群 Oracle 12c 在集群安装时支持两类配置:传统标准集群和Flex集群.在一个传统标准集 ...

最新文章

  1. (98)Address already in use: make_sock: could not bind to address 0.0.0.0:80
  2. xslt 标签取集合第一条数据_XSLT函数集合:数值函数、字符串函、节点集函数和布尔函数...
  3. linux 内存不足时候 应该及时回收page cache
  4. P3531 [POI2012]LIT-Letters(求逆序对)
  5. 如何隐藏storyboard中的top bar
  6. MFC——在视图窗口加载背景图片
  7. STM32F1笔记(七)WWDG窗口看门狗
  8. JavaScript 基础 数据类型与运算符
  9. CHM文件打开显示乱码的解决方法
  10. Oracle diag目录下面的大量trace trc文件
  11. 用csc手动编译和Ildasm反编译
  12. PAT乙级1005. 继续(3n+1)猜想 (25)
  13. Java的继承和python的继承_Java ,python面向对象的继承及其区别
  14. linux 卡在grub_关于linux开机进入grub问题的解决方法
  15. 非标准的CAN波特率计算
  16. 计算机主机可以有几个硬盘,一台电脑可以安装盘几个硬盘?
  17. Win10系统默认Administrator账号没有管理员权限的解决方案(win10专业版亲测)
  18. 脑肠轴——看不见的Crosstalk
  19. Gamit Gloness 数据处理 流程
  20. SpringBoot高级_与安全

热门文章

  1. 对eventloop的研究
  2. 常用模块之 time,datetime,random,os,sys
  3. pycharm(windows)安装及其设置中文菜单
  4. 理解Go Interface
  5. iOS回顾笔记( 02 ) -- 由九宫格布局引发的一系列“惨案”
  6. LeetCode() Word Search II
  7. 计算机专业单元测试卷答案,银保监会考试题库:计算机类模拟试题练习(六)答案...
  8. Teams Bot库的JSON
  9. plex实现流媒体服务器_如何从Plex Media Server离线查看下载和同步媒体
  10. java B2B2C 仿淘宝电子商城系统-Spring Cloud Eureka参数配置项详解