广告位联系
返回顶部

C# yeild的使用

C#教程 来源:互联网 作者:佚名 发布时间:2026-10-10 16:33:13 人浏览
摘要

yield 是 C# 中一个非常巧妙的语法糖,它的核心作用是实现延迟执行(Lazy Evaluation)。 简单来说,它允许你在一个方法中逐个返回数据,而不需要一次性把所有数据都计算好并塞进一个 List 里返

yield 是 C# 中一个非常巧妙的语法糖,它的核心作用是实现“延迟执行(Lazy Evaluation)”。

简单来说,它允许你在一个方法中逐个返回数据,而不需要一次性把所有数据都计算好并塞进一个 List 里返回。

???? 核心概念:从“批发”到“零售”

为了理解 yield,我们先看一个不使用 yield 的传统写法:

1

2

3

4

5

6

7

8

9

10

// 传统写法:一次性生成所有数据(批发)

public List<int> GetNumbers(int count)

{

    var list = new List<int>();

    for (int i = 0; i < count; i++)

    {

        list.Add(i); // 把所有数字都塞进内存里的集合

    }

    return list; // 最后一次性返回整个集合

}

缺点:如果 count 是 100 万,这个方法会瞬间在内存中分配一个包含 100 万个元素的数组,造成极大的内存浪费。

现在看看使用 yield 的写法:

1

2

3

4

5

6

7

8

// yield 写法:按需生成数据(零售)

public IEnumerable<int> GetNumbersYield(int count)

{

    for (int i = 0; i < count; i++)

    {

        yield return i; // 每次吐出一个数字,然后“暂停”在这里

    }

}

优点:调用这个方法时,它根本不会立刻执行循环。只有当外部真正去读取下一个数据时,它才会执行一次循环,吐出一个值,然后暂停。内存中永远只存在当前这一个数字。

????? 两个核心关键字

  1. yield return:返回当前值,并记住当前的执行状态(包括局部变量、循环索引等)。下次调用时,直接从这行代码的下一行继续执行。
  2. yield break:提前结束迭代,相当于普通方法里的 return。

???? 典型应用场景

1. 读取超大文件或数据流

假设你要读取一个 10GB 的日志文件,如果用 File.ReadAllLines(),内存直接撑爆。用 yield 可以逐行处理:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

public IEnumerable<string> ReadLargeFile(string filePath)

{

    using (var reader = new StreamReader(filePath))

    {

        string line;

        while ((line = reader.ReadLine()) != null)

        {

            yield return line; // 读一行,吐出一行,内存占用极小

        }

    }

}

 

// 使用时:

foreach (var line in ReadLargeFile("huge_log.txt"))

{

    if (line.Contains("ERROR")) Console.WriteLine(line);

}

2. 实现自定义迭代器

如果你想让你自己写的类支持 foreach 循环,就可以用 yield:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

public class Countdown

{

    private int _start;

    public Countdown(int start) { _start = start; }

 

    public IEnumerator<int> GetEnumerator()

    {

        for (int i = _start; i >= 0; i--)

        {

            yield return i;

        }

    }

}

 

// 使用时:

var countdown = new Countdown(5);

foreach (var num in countdown)

{

    Console.WriteLine(num); // 输出 5, 4, 3, 2, 1, 0

}

3. 提前终止(yield break)

1

2

3

4

5

6

7

8

9

public IEnumerable<int> GetEvenNumbers(int max)

{

    for (int i = 0; i <= max; i++)

    {

        if (i > 10) yield break; // 如果超过10,直接结束整个迭代

         

        if (i % 2 == 0) yield return i;

    }

}

?? 必须注意的“坑”

  1. 只能返回特定类型:包含 yield 的方法,返回类型只能是 IEnumerable、IEnumerable<T>、IEnumerator 或 IEnumerator<T>。不能直接返回 List<T> 或数组。
  2. 延迟执行的副作用:

    1

    2

    3

    4

    var query = GetNumbersYield(100); // 此时循环一次都没执行!

     

    // 只有走到这里,循环才开始

    foreach(var item in query) { ... }

    如果你在 GetNumbersYield 里面有参数校验(比如 if(count < 0) throw...),在调用方法时不会报错,只有在 foreach 第一次迭代时才会报错。
  3. 不要在 yield 方法里使用 try-catch-finally 包裹 yield return:C# 编译器不允许在包含 yield return 的 try 块中使用 catch(但可以使用 finally)。

???? 总结

yield 的本质是状态机。C# 编译器在底层帮你把 yield 方法编译成了一个复杂的类,自动帮你保存了局部变量和执行位置。

一句话口诀:当数据量很大,或者数据是按需生成的,且你只需要用 foreach 去遍历它时,果断使用 yield return。


版权声明 : 本文内容来源于互联网或用户自行发布贡献,该文观点仅代表原作者本人。本站仅提供信息存储空间服务和不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权, 违法违规的内容, 请发送邮件至2530232025#qq.cn(#换@)举报,一经查实,本站将立刻删除。
原文链接 :
相关文章
  • C# Thread和Task的区别
    在 C# 中,Thread 和 Task 都用于实现并发(Concurrency) 和 异步编程(Asynchronous Programming),但它们在设计目标、使用方式、资源管理、抽象层
  • C# yeild的使用
    yield 是 C# 中一个非常巧妙的语法糖,它的核心作用是实现延迟执行(Lazy Evaluation)。 简单来说,它允许你在一个方法中逐个返回数据,而不
  • C#调用千问、DS、智谱等AI时实现记忆与Token节省方
    在 C# 中调用千问(Qwen)、DS(通义千问)和智谱(如 GLM)等大模型时,记忆机制(Memory)和Token 消耗优化是提升交互体验和降低成本的关键
  • C#上位机多线程介绍
    C# 多线程的四种打开方式 C# 发展到今天,多线程的写法也经历了几代演变。你不需要全都精通,但至少要知道它们是什么、什么时候用。
  • C#三步实现Word转Excel并保留格式

    C#三步实现Word转Excel并保留格式
    在许多业务流程中,重要数据通常以 Word 文档的形式存在,例如报告、发票、客户清单或其他结构化列表。Microsoft Word 在排版、格式化和展
  • C#代码实现生成带Logo的二维码
    在生成二维码时,您可能希望在其中加入自定义图片,例如公司的 Logo 或个人头像。本文将介绍如何使用Spire.Barcode for .NET库,通过C# 和 VB
  • C#使用Spire.PDF实现PDF与OFD的互转
    在日常办公和电子文档处理中,PDF和OFD是两种最常见的电子文档格式。PDF作为国际通用格式广为人知,而OFD作为国家标准版式文档格式,在
  • 使用C#创建PDF文档的完整教程(文本、图片、形状

    使用C#创建PDF文档的完整教程(文本、图片、形状
    在企业级应用和信息系统中,PDF 一直是最常见、也是最稳定的文档输出格式之一。无论是财务报表、合同文档、业务统计报告,还是系统自
  • C# Spire.XLS for .NET轻松实现Excel到TXT的转换
    在数据处理领域,Excel文件以其强大的功能占据着举足轻重的地位。然而,在诸多应用场景下,我们却需要将这些结构化的Excel数据转换为更
  • C#中弱引用使用介绍

    C#中弱引用使用介绍
    弱引用(Weak Reference)是一种特殊的引用类型,它允许你引用一个对象,但不会阻止该对象被垃圾回收器(GC)回收。弱引用通常用于需要缓
  • 本站所有内容来源于互联网或用户自行发布,本站仅提供信息存储空间服务,不拥有版权,不承担法律责任。如有侵犯您的权益,请您联系站长处理!
  • Copyright © 2017-2022 F11.CN All Rights Reserved. F11站长开发者网 版权所有 | 苏ICP备2022031554号-1 | 51LA统计