IEnumerable 接口是 C# 开发过程中非常重要的接口,对于其特性和用法的了解是十分必要的。本文将通过10个小例子,来熟悉一下其简单的用法。

全是源码

以下便是这10个小例子,响应的说明均标记在注释中。

每个以 TXX 开头命名的均是一个示例。建议从上往下阅读。

using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using FluentAssertions;
using Xunit;
using Xunit.Abstractions; namespace Try_More_On_IEnumerable
{
public class EnumerableTests
{
private readonly ITestOutputHelper _testOutputHelper; public EnumerableTests(
ITestOutputHelper testOutputHelper)
{
_testOutputHelper = testOutputHelper;
} [Fact]
public void T01普通的循环获取偶数()
{
// 创建一个集合存放最终结果
var result = new List<int>();
for (var i = 0; i <= 10; i++)
{
// 如果是偶数的话,将数字放入集合中
if (i % 2 == 0)
{
result.Add(i);
}
} // 断言最终的结果
result.Should().Equal(0, 2, 4, 6, 8, 10);
} [Fact]
public void T02普通Enumerable()
{
// 通过静态方法获取偶数的Enumerable对象
var result = GetNumber(10); // 断言结果
result.Should().Equal(0, 2, 4, 6, 8, 10); /**
* 这种写法比起 T01 的写法少了一个集合的创建,通常来说是性能更佳的写法
*/
} /// <summary>
/// 获取小于等于max的偶数
/// </summary>
/// <param name="max"></param>
/// <returns></returns>
private static IEnumerable<int> GetNumber(int max)
{
for (var i = 0; i <= max; i++)
{
if (i % 2 == 0)
{
// 使用 yield return 返回每次迭代的结果
yield return i;
}
}
} [Fact]
public void T02本地函数()
{
// 通过本地函数获取结果
var result = GetNumber(10); // 断言结果
result.Should().Equal(0, 2, 4, 6, 8, 10); /**
* 使用本地函数获取 Enumerable 对象。
* 此处的效果和静态方法类似。
* 本地函数是 C# 7.0 才开始支持的语法特性。
* 关于本地函数详细内容可以参见:https://docs.microsoft.com/zh-cn/dotnet/csharp/programming-guide/classes-and-structs/local-functions
*/
IEnumerable<int> GetNumber(int max)
{
for (var i = 0; i <= max; i++)
{
if (i % 2 == 0)
{
yield return i;
}
}
}
} [Fact]
public void T03分离条件()
{
/**
* 使用 Where 过滤结果
* 这样的做法分离了“自增”逻辑和“判断是偶数”的逻辑
*/
var result = GetNumber(10)
.Where(x => x % 2 == 0); result.Should().Equal(0, 2, 4, 6, 8, 10); // 迭代时只是进行了自增操作
IEnumerable<int> GetNumber(int max)
{
for (var i = 0; i <= max; i++)
{
yield return i;
}
}
} [Fact]
public void T04Linq产生数值()
{
// 系统内置了一个方法来获取数字的自增序列,因此可以如此简化
var result = Enumerable
.Range(0, 11)
.Where(x => x % 2 == 0); result.Should().Equal(0, 2, 4, 6, 8, 10);
} [Fact]
public void T05输出233()
{
// 输出3个数字 233
var result = Get233().Take(3);
result.Should().Equal(2, 3, 3); // 输出5个数字 23333
result = Get233().Take(5);
result.Should().Equal(2, 3, 3, 3, 3); IEnumerable<int> Get233()
{
// 第一次输出 2
yield return 2;
while (true)
{
// 后面都输出 3
yield return 3;
}
} /**
* 值得注意的是 while(true) 并不会导致程序陷入死循环
* 因为 yield return 是采用按需供给的方式执行的。
* 关于这点可以参考右侧文章:https://www.cnblogs.com/SilentCode/p/5014068.html
*/
} [Fact]
public void T06获取10个小于50的随机数()
{
/**
* 过滤随机数中小于50的数字,只获取其中10个结果
*/
var result = GetRandom()
.Where(x => x < 50)
.Take(10)
.ToArray(); // 断言
result.Should().HaveCount(10);
result.All(x => x < 50).Should().BeTrue(); IEnumerable<int> GetRandom()
{
var random = new Random();
// 不断输出 0-100 的随机数
while (true)
{
yield return random.Next(0, 100);
}
}
} [Fact]
public void T07自动补足随机数()
{
// 获取3个数字
var result1 = GetData().Take(3); // 3 个数字分别为 0,1,2
result1.Should().Equal(0, 1, 2); // 获取 10 个数字
var result2 = GetData().Take(10).ToArray(); // 前 5 个数字分别为 0,1,2,3,4
result2.Take(5).Should().Equal(0, 1, 2, 3, 4);
// 从第 5 个开始的数字都大于 10
result2.Skip(5).Take(5).Should().Match(x => x.All(a => a > 10)); /**
* 获取一组数据,前5个数字是 0,1,2,3,4 。后面继续获取则为随机数
*/
IEnumerable<int> GetData()
{
var staticData = new[] {0, 1, 2, 3, 4};
foreach (var i in staticData)
{
yield return i;
} var random = new Random();
// 不断输出 10-100 的随机数
while (true)
{
yield return random.Next(10, 100);
}
}
} [Fact]
public void T08条件转循环()
{
var book1 = GetReadingBook(DateTime.Parse("2019-08-30")).First();
book1.Should().Be("每个周五都是快乐的一天"); var book2 = GetReadingBook(DateTime.Parse("2016-02-29")).First();
book2.Should().Be("四年一次的邂逅"); var book3 = GetReadingBook(DateTime.Parse("2019-09-01")).First();
book3.Should().BeSameAs("月老板软件开发小妙招三十二则"); // 获取给定时间需要阅读的书籍名称
IEnumerable<string> GetReadingBook(DateTime time)
{
// 周五
if (time.DayOfWeek == DayOfWeek.Friday)
{
yield return "每个周五都是快乐的一天";
} // 2月29日
if (time.Date.Month == 2 && time.Date.Day == 29)
{
yield return "四年一次的邂逅";
} // 其他时间阅读名著
yield return "月老板软件开发小妙招三十二则";
}
} [Fact]
public void T09获取一个链接字符串()
{
// 获取一个当前可用的链接字符串
var conn = GetConnectionString().FirstOrDefault();
conn.Should().Be("Source=赛博坦;UID=月x;Password=******"); IEnumerable<string> GetConnectionString()
{
// 从一个文件中获取链接字符串
var connFilename = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "conn.txt");
if (File.Exists(connFilename))
{
var fileContent = File.ReadAllText(connFilename);
yield return fileContent;
} // 从配置文件中读取链接字符串
var dbConnectionString = ConfigurationManager.ConnectionStrings["db"]?.ConnectionString;
if (!string.IsNullOrEmpty(dbConnectionString))
{
yield return dbConnectionString;
} // 返回默认的字符串
yield return "Source=赛博坦;UID=月x;Password=******";
}
} [Fact]
public async Task T10测试网络连接()
{
var httpClient = new HttpClient();
try
{
await Task.WhenAll(SendRequests());
_testOutputHelper.WriteLine("当前网络连接正常");
}
catch (Exception e)
{
_testOutputHelper.WriteLine("当前网络不正常,请检查网络连接");
} IEnumerable<Task> SendRequests()
{
yield return Task.Run(() => httpClient.GetAsync("http://www.baidu.com"));
yield return Task.Run(() => httpClient.GetAsync("http://www.bing.com"));
yield return Task.Run(() => httpClient.GetAsync("http://www.taobao.com"));
}
}
}
}

  

源码说明

以上示例的源代码放置于博客示例代码库中。

项目采用 netcore 2.2 作为目标框架,因此需要安装 netcore 2.2 SDK 才能运行。

试试 IEnumerable 的 10 个小例子的更多相关文章

  1. activiti 用户手册中 10分钟 小例子 简单代码搭建 及 其中的 各种坑

    看mossle的 5.16 用户手册中的  快速起步:10分钟教程 想自己跑一下,虽然官方文档已经写的非常详细了,但是实际操作中还是遇到各种坑,这里记录下来. 首先官网下载最新的 5版本 full G ...

  2. 试试 IEnumerable 的另外 6 个小例子

    IEnumerable 接口是 C# 开发过程中非常重要的接口,对于其特性和用法的了解是十分必要的.本文将通过6个小例子,来熟悉一下其简单的用法. <!-- more --> 阅读建议 在 ...

  3. c小例子 10个数找出第一名

    这个小例子,是从十个数中找到第一名,如果第一名的分数相同,则二者都可以晋级,进入下一轮比赛,我们就对这个数进行排序,这样要求输出晋级人员的标号0-9号中其中一个或几个. 如何用c语言来实现呢? 1) ...

  4. Runtime的几个小例子(含Demo)

    一.什么是runtime(也就是所谓的“运行时”,因为是在运行时实现的.)           1.runtime是一套底层的c语言API(包括很多强大实用的c语言类型,c语言函数);  [runti ...

  5. python2.7练习小例子(十)

        10):古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少?     程序分析:兔子的规律为数列1,1 ...

  6. c# BackGroundWorker 多线程操作的小例子

    在我们的程序中,经常会有一些耗时较长的运算,为了保证用户体验,不引起界面不响应,我们一般会采用多线程操作,让耗时操作在后台完成,完成后再进行处理或给出提示,在运行中,也会时时去刷新界面上的进度条等显示 ...

  7. ASP.NET Cookie对象到底是毛啊?(简单小例子)

    记得刚接触asp.net的时候,就被几个概念搞的头痛不已,比如Request,Response,Session和Cookie.然后还各种在搜索引擎搜,各种问同事的,但是结果就是自己还是很懵的节奏. 那 ...

  8. 【unity3d游戏开发之基础篇】unity3d射线的原理用法以及一个利用射线实现简单拾取的小例子

    原地址:http://www.cnblogs.com/xuling/archive/2013/03/04/2943154.html 最近开始研究U3D,它的强大就不多说了, 今天研究了研究射线相关东西 ...

  9. 五个小例子教你搞懂 JavaScript 作用域问题

    众所周知,JavaScript 的作用域和其他传统语言(类C)差别比较大,掌握并熟练运用JavaScript 的作用域知识,不仅有利于我们阅读理解别人的代码,也有助于我们编写自己的可靠代码. 下面笔者 ...

随机推荐

  1. 我造了个好大的"轮子",居然还不是"圆"的!

      我造的这个"轮子"指的是集低代码开发与运维为一体的平台,为什么说它不是"圆"的,因为它有些与众不同,甚至可以说是有些另类.至于为什么造这个"轮子& ...

  2. jsp数据交互(二).1

    对象的作用域:   JSP中提供了四种作用域,分别是page作用域,request作用域,session作用域和application作用域. page作用域: page作用域指单一JSP页面的范围, ...

  3. web设计_3_可伸缩的导航栏

    1. HTML5构建一个选项卡,需要<nav>标签包围一个无序列表,也可以添加role属性告诉辅助设备(如屏幕阅读器)这个元素所扮演的角色. 绝对不要基于图片的导航,对搜索引擎不友好,更新 ...

  4. Linux中bash shell环境变量

    别名 别名是命令的快捷方式.为那些需要经常执行,但需要很长时间输入的长命令创建快捷方式很有用.语法是: alias ppp='ping www.baidu.com' 它们并不总是用来缩短长命令.重要的 ...

  5. 金蝶K3 V12.2版本,中途启用双计量单位出现错误

    忘记修改虚仓库存/收料通知单的双计量数量

  6. Asp.Net Core 发布到 Docker(Linux Centos 虚拟机,使用Dockerfile)

    实践一下 Asp.Net Core (基于.net core 2.2)部署到Docker 一.准备工作: 1. 使用Virtualbox创建一个Centos系统的虚拟机,并安装docker和vim 2 ...

  7. Python基础总结之认识lambda函数、map函数、filter() 函数。第十二天开始(新手可相互督促)

    今天周日,白天在学习,晚上更新一些笔记,希望对大家能更好的理解.学习python~ lambda函数,也就是大家说的匿名函数.它没有具体的名称,也可以叫做一句话函数,我觉得也不过分,大家看下代码,来体 ...

  8. 自练Eclipse搭建SSH全自动注解博客项目笔记

    1.创建一个动态的java项目 2.导入搭建所需要的jar包 3.配置web.xml文件 1).头文件 2).struts2的拦截器 3).定位加载Spring容器的配置文件 4).监听 5). 6) ...

  9. Jenkins 持续集成持续发布使用搭建基础

    一.环境搭建基础 1.持续集成.持续交付.持续部署概念 ①.集成: 是指软件多人研发的部分软件代码整合交付,以便尽早发现个人开发部分的问题:持续集成:强调开发人员提交了新代码之后,立刻进行构建(单元) ...

  10. Kafka学习(四)-------- Kafka核心之Producer

    通过https://www.cnblogs.com/tree1123/p/11243668.html 已经对consumer有了一定的了解.producer比consumer要简单一些. 一.旧版本p ...