在 C# 9 中使用 foreach 扩展
在 C# 9 中,foreach 循环可以使用扩展方法。在本文中,我们将通过例子回顾 C# 9 中如何扩展 foreach 循环。
代码演示
下面是一个对树形结构进行深度优先遍历的示例代码:
using System;
using System.Collections.Generic;
namespace Example
{
class TreeNode
{
public int Value { get; set; }
public List<TreeNode> Children { get; set; }
public TreeNode(int value)
{
Value = value;
Children = new List<TreeNode>();
}
}
static class TreeExtensions
{
public static IEnumerable<TreeNode> DepthFirst(this TreeNode root)
{
yield return root;
foreach (var child in root.Children.SelectMany(DepthFirst))
{
yield return child;
}
}
}
class Program
{
static void Main(string[] args)
{
var root = new TreeNode(1);
root.Children.Add(new TreeNode(2));
root.Children.Add(new TreeNode(3));
root.Children[0].Children.Add(new TreeNode(4));
root.Children[0].Children.Add(new TreeNode(5));
foreach (var node in root.DepthFirst())
{
Console.WriteLine(node.Value);
}
// Outputs: 1 2 4 5 3
}
}
}
在这个示例代码中,我们在 TreeNode 类中定义了一个值属性和一个存储子节点的列表属性。我们还在 TreeExtensions 类中定义了一个 DepthFirst 扩展方法,该方法使用 yield return 语句来返回树形结构的深度优先遍历结果。
在 Main 方法中,我们创建了一个树形结构,然后使用 foreach 循环来遍历树形结构的深度优先遍历结果。
之所以使用扩展方法往往是因为,我们可以在不修改 TreeNode 类的情况下,为 TreeNode 类添加新的功能。
那么接下来我们希望在 C# 9 中默认为 TreeNode 类添加 DepthFirst 行为,这样我们就可以直接使用 foreach 循环来遍历树形结构的深度优先遍历结果了。
C# 9 中的 foreach 扩展
在 C# 9 中,我们可以使用 foreach 扩展来实现上面的需求。我们只需要在 TreeNode 类中添加一个 GetEnumerator 方法,该方法返回一个实现了 IEnumerable 接口的对象即可。
static class TreeExtensions
{
public static IEnumerable<TreeNode> DepthFirst(this TreeNode root)
{
yield return root;
foreach (var child in root.Children.SelectMany(DepthFirst))
{
yield return child;
}
}
public static IEnumerator<TreeNode> GetEnumerator(this TreeNode root)
{
return root.DepthFirst().GetEnumerator();
}
}
在上面的代码中,我们在 TreeNode 类中添加了一个 GetEnumerator 方法,该方法返回一个实现了 IEnumerable 接口的对象。这个对象就是我们在 DepthFirst 方法中使用 yield return 语句返回的结果。
现在我们可以直接使用 foreach 循环来遍历树形结构的深度优先遍历结果了。
foreach (var node in root)
{
Console.WriteLine(node.Value);
}
总结
在 C# 9 中,我们可以使用 foreach 扩展来为类添加新的行为。在上面的示例代码中,我们为 TreeNode 类添加了 DepthFirst 行为,这样我们就可以直接使用 foreach 循环来遍历树形结构的深度优先遍历结果了。
参考资料
- Extension GetEnumerator support for foreach loops[1]
- 本文作者: newbe36524
- 本文链接: https://www.newbe.pro/ChatAI/0x013-Extension-foreach-in-csharp-9/
- 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
参考资料
[1]
Extension GetEnumerator support for foreach loops: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-9.0/extension-getenumerator?WT.mc_id=DX-MVP-5003606
在 C# 9 中使用 foreach 扩展的更多相关文章
- 如何正确看待Linq的DistinctBy扩展和ForEach扩展
在微软标准的Linq中,并没有DistinctBy扩展和ForEach扩展,但在平时使用工作中却又经常需要使用到这两个功能,照理来说,微软在Linq中应该包含这两个扩展才对,可事实上为什么并没有呢?本 ...
- EntityFramework 中支持 BulkInsert 扩展
本文为 Dennis Gao 原创技术文章,发表于博客园博客,未经作者本人允许禁止任何形式的转载. 前言 很显然,你应该不至于使用 EntityFramework 直接插入 10W 数据到数据库中,那 ...
- javascript中的数组扩展(一)
javascript中的数组扩展(一) 随着学习的深入,发现需要学习的关于数组的内容也越来越多,后面将会慢慢归纳,有的是对前面的强化,有些则是关于前面的补充. 一.数组的本质 数组是按照次序排 ...
- EntityFramework中支持BulkInsert扩展(转载)
前言 很显然,你应该不至于使用 EntityFramework 直接插入 10W 数据到数据库中,那可能得用上个几分钟.EntityFramework 最被人诟病的地方就是它的性能,处理大量数据时的效 ...
- 浅析Thinkphp框架中运用phprpc扩展模式
浅析Thinkphp框架中应用phprpc扩展模式 这次的项目舍弃了原来使用Axis2做web服务端的 方案,改用phprpc实现,其一是服务端的thinkphp已集成有该模式接口,其二是phprpc ...
- .NET系统开发过程中积累的扩展方法
分享.NET系统开发过程中积累的扩展方法 .NET 3.5提供的扩展方法特性,可以在不修改原类型代码的情况下扩展它的功能.下面分享的这些扩展方法大部分来自于Code Project或是Stacko ...
- EntityFramework中支持BulkInsert扩展
EntityFramework中支持BulkInsert扩展 本文为 Dennis Gao 原创技术文章,发表于博客园博客,未经作者本人允许禁止任何形式的转载. 前言 很显然,你应该不至于使用 Ent ...
- JS中的forEach、$.each、map方法推荐
下面小编就为大家带来一篇JS中的forEach.$.each.map方法推荐.小编觉得挺不错的,现在分享给大家,也给大家做个参考.一起跟随小编过来看看吧 orEach是ECMA5中Array新方法中最 ...
- 集合中的 for-Each循环
数组的加强型的for-Each循环很简单,我们再来看一下集合中的for-Each 循环又是怎么样的.我们都知道集合中的遍历都是通过迭代(iterator)完成的.也许有人说,也可以按照下面的方式来遍 ...
- PHP中的IMAP扩展简单入门
对于邮件处理来说,大家比较熟悉的应该是 POP3 . SMTP 这类的协议,而今天我们介绍的 IMAP 其实也是非常常用的一种邮件处理协议.它和 POP3 比较类似,都是以接收处理邮件为主.不过相对于 ...
随机推荐
- Failed to convert from type [java.lang.String] to type [java.util.Date] for value '2020-02-06'; nested exception is java.lang.IllegalArgumentException]解决
今天做springbook项目前端输入日期传到数据库保存报了一下错误 Whitelabel Error Page This application has no explicit mapping fo ...
- 强国杯东杯分区赛miscwp
目录 不要被迷惑 PCAP文件分析 平正开 不要被迷惑 编辑 导出http 编辑 得到flag.zip后直接爆破密码 编辑 得到编辑 然后一键解码 编辑 flag{WImuJeqSNPh ...
- Java编程基础——敬请期待!!!
变量 数据类型 条件判断 循环 函数 类 Java特性
- java中实现File文件的重命名(renameTo)、将文件移动到其他目录下、文件的复制(copy)、目录和文件的组合(更加灵活方便)
欢迎加入刚建立的社区:http://t.csdn.cn/Q52km 加入社区的好处: 1.专栏更加明确.便于学习 2.覆盖的知识点更多.便于发散学习 3.大家共同学习进步 3.不定时的发现金红包(不多 ...
- 支持JDK19虚拟线程的web框架,之一:体验
欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 关于虚拟线程 随着JDK19 GA版本的发布,虚拟线程 ...
- GIT入门与Gitee的使用
一:Git是什么? Git是目前世界上最先进的分布式版本控制系统. 工作原理 / 流程: Workspace:工作区Index / Stage:暂存区Repository:仓库区(或本地仓库)Remo ...
- xlwings 模块总结
基本使用 在子线程中使用时,有时需要在子线程函数中加入以下.有时不需要加入,目前还不明白具体的原因 import pythoncom # 导入的库 pythoncom.CoInitialize() # ...
- C# 多线程访问之 SemaphoreSlim(信号量)【C# 进阶】
SemaphoreSlim 是对可同时访问某一共享资源或资源池的线程数加以限制的 Semaphore 的轻量替代,也可在等待时间预计很短的情况下用于在单个进程内等待. 由于 SemaphoreSlim ...
- Nginx负载均衡策略的介绍与调优
工作中经常会用到nginx负载均衡这一块,下面对nginx负载均衡策略做个总结.本人在工作中最常用到的负载均衡策略是轮询策略. 在一般情况下,Web中间件最大的作用就是负责对请求进行分发,也就是我们常 ...
- java学习之IO流
java io流有四大家族分别是: 1.InputStream(字节输入流) 2.OutputStream(字节输入出流)3.Reader(字符输入流)4.Writer(字符输出流)四个类都是抽象类 ...