.NET 帮助

C# Yield Return(对开发者的工作原理)

Chipego
奇佩戈-卡琳达
2024年一月27日
分享:

C# 是微软开发的最流行的编程语言之一,它提供的功能可为您的代码增添优雅和高效。 其中一个功能是 yield 关键字,它首次在 C# 2.0 中引入。 Microsoft 提供了一个关于 yield 关键字语句的完整语言参考,以便探索在迭代器方法中使用它们的更多信息,您可以在Microsoft 官方文档中查看关于 yield 的信息

在本文中,我们将探讨C#中的yield return,研究其功能、应用场景以及它如何改变您处理迭代的方法。

理解基础知识:C#中的迭代

迭代是编程中的一个基本概念,C# 提供了实现迭代的各种机制。 传统上,像forforeach循环这样的循环一直是遍历集合的常用工具。 然而,C# 引入了一个更优雅的解决方案,将yield关键字应用于return语句,并通过IEnumerable接口来实现。

yield return语句的效率

本质上,yield return 是在迭代器方法中使用的语句,用于提供更高效的方式生成值序列。 它允许您创建一个迭代器,而无需在内存中生成整个集合,因此对大型数据集或无限序列特别有用。

下面是一个简单的代码片段,用于说明yield return的基本用法:

public IEnumerable<int> GenerateNumbers(int start, int end)
{
    // for loop goes through numbers, start to end
    for (int i = start; i <= end; i++) 
    {
        yield return i; // returns each number without breaking the loop
    }
}

// Usage
// foreach loop calls the previous function
foreach (var number in GenerateNumbers(1, 5)) 
{
    Console.WriteLine(number); // Outputs numbers 1 - 5
}
public IEnumerable<int> GenerateNumbers(int start, int end)
{
    // for loop goes through numbers, start to end
    for (int i = start; i <= end; i++) 
    {
        yield return i; // returns each number without breaking the loop
    }
}

// Usage
// foreach loop calls the previous function
foreach (var number in GenerateNumbers(1, 5)) 
{
    Console.WriteLine(number); // Outputs numbers 1 - 5
}
Public Iterator Function GenerateNumbers(ByVal start As Integer, ByVal [end] As Integer) As IEnumerable(Of Integer)
	' for loop goes through numbers, start to end
	For i As Integer = start To [end]
		Yield i ' returns each number without breaking the loop
	Next i
End Function

' Usage
' foreach loop calls the previous function
For Each number In GenerateNumbers(1, 5)
	Console.WriteLine(number) ' Outputs numbers 1 - 5
Next number
$vbLabelText   $csharpLabel

在此示例中,GenerateNumbers 方法使用 yield return 来生成从 startend 的数字序列。 迭代器采用懒惰评估方式,这意味着每个数字都是在迭代执行过程中按需生成的。

懒惰评估和效率

yield return 语句的一个显著优势是其支持惰性求值的能力。 与在迭代之前生成整个集合的传统方法不同,yield return 一次生成一个值。这可以显著节省内存,尤其是在处理大数据集时。

有状态迭代:处理复杂场景

yield return 语句不仅限于生成简单的序列; 它擅长处理迭代块中更复杂的情况。 通过维护跨迭代的状态机,您可以创建能够记住其在序列中位置的迭代器。

public IEnumerable<string> GenerateFibonacci(int count)
{
    int a = 0, b = 1;
    for (int i = 0; i < count; i++)
    {
        yield return a.ToString(); // returns 'a' value in the middle of the for loop
        int temp = a;
        a = b;
        b = temp + b;
    }
}
// Usage
// foreach loop that calls the previous iterator function
foreach (var fibNumber in GenerateFibonacci(8))
{
    Console.WriteLine(fibNumber); // Outputs a Fibonacci number sequence
}
public IEnumerable<string> GenerateFibonacci(int count)
{
    int a = 0, b = 1;
    for (int i = 0; i < count; i++)
    {
        yield return a.ToString(); // returns 'a' value in the middle of the for loop
        int temp = a;
        a = b;
        b = temp + b;
    }
}
// Usage
// foreach loop that calls the previous iterator function
foreach (var fibNumber in GenerateFibonacci(8))
{
    Console.WriteLine(fibNumber); // Outputs a Fibonacci number sequence
}
Public Iterator Function GenerateFibonacci(ByVal count As Integer) As IEnumerable(Of String)
	Dim a As Integer = 0, b As Integer = 1
	For i As Integer = 0 To count - 1
		Yield a.ToString() ' returns 'a' value in the middle of the for loop
		Dim temp As Integer = a
		a = b
		b = temp + b
	Next i
End Function
' Usage
' foreach loop that calls the previous iterator function
For Each fibNumber In GenerateFibonacci(8)
	Console.WriteLine(fibNumber) ' Outputs a Fibonacci number sequence
Next fibNumber
$vbLabelText   $csharpLabel

在此示例中,GenerateFibonacci 方法使用 yield return 来创建斐波那契数列。 在迭代之间保持状态,确保高效生成和输出斐波那契数字。

构建无限序列

yield return 的一个有趣应用是其能够创建无限的值序列。 由于值是即时生成的,因此您可以表示永远持续下去的序列,而不会消耗无限的内存。

public IEnumerable<int> GenerateEvenNumbers()
{
    int num = 0;
    while (true)
    {
        yield return num;
        num += 2;
    }
}

// Usage
var evenNumberIterator = GenerateEvenNumbers().GetEnumerator();
for (int i = 0; i < 5; i++)
{
    evenNumberIterator.MoveNext();
    Console.WriteLine(evenNumberIterator.Current);
}
public IEnumerable<int> GenerateEvenNumbers()
{
    int num = 0;
    while (true)
    {
        yield return num;
        num += 2;
    }
}

// Usage
var evenNumberIterator = GenerateEvenNumbers().GetEnumerator();
for (int i = 0; i < 5; i++)
{
    evenNumberIterator.MoveNext();
    Console.WriteLine(evenNumberIterator.Current);
}
Public Iterator Function GenerateEvenNumbers() As IEnumerable(Of Integer)
	Dim num As Integer = 0
	Do
		Yield num
		num += 2
	Loop
End Function

' Usage
Private evenNumberIterator = GenerateEvenNumbers().GetEnumerator()
For i As Integer = 0 To 4
	evenNumberIterator.MoveNext()
	Console.WriteLine(evenNumberIterator.Current)
Next i
$vbLabelText   $csharpLabel

在这个例子中,GenerateEvenNumbers 方法创建了一个偶数的迭代器,您可以根据需要迭代它。 您还可以使用yield break语句与yield return一起停止并退出循环,从而为循环创建自定义迭代。

介绍 IronPDF:强大的 C# 库

C# Yield Return(它如何为开发人员工作):图 1 - IronPDF 网页

IronPDF 是一个多功能的 C# 库,旨在简化处理 PDF 的复杂性。 无论您是要生成发票、报告还是其他任何文档,IronPDF 都能让您在 C# 应用程序中直接将 HTML 内容无缝转换为精美、专业的 PDF。

安装 IronPDF:快速入门

要将 IronPDF 纳入您的 C# 项目,您可以迅速安装 IronPDF NuGet 软件包。 在软件包管理器控制台中执行以下命令:


安装-打包 IronPdf

或者,您也可以在 NuGet 包管理器中找到 "IronPdf",然后从那里进行安装。

使用 IronPDF 生成 PDF

使用 IronPDF 创建 PDF 是一个简单明了的过程。 让我们举一个基本的例子:

var htmlContent = "<html><body><h1>Hello, IronPDF!</h1></body></html>";
// Create a new PDF document
var pdfDocument = new IronPdf.ChromePdfRenderer();
pdfDocument.RenderHtmlAsPdf(htmlContent).SaveAs("C:/GeneratedDocument.pdf");
var htmlContent = "<html><body><h1>Hello, IronPDF!</h1></body></html>";
// Create a new PDF document
var pdfDocument = new IronPdf.ChromePdfRenderer();
pdfDocument.RenderHtmlAsPdf(htmlContent).SaveAs("C:/GeneratedDocument.pdf");
Dim htmlContent = "<html><body><h1>Hello, IronPDF!</h1></body></html>"
' Create a new PDF document
Dim pdfDocument = New IronPdf.ChromePdfRenderer()
pdfDocument.RenderHtmlAsPdf(htmlContent).SaveAs("C:/GeneratedDocument.pdf")
$vbLabelText   $csharpLabel

在上面的示例中,IronPDF用于将HTML内容渲染为PDF文档,然后将其保存到指定位置。 有关更多详细信息,请访问IronPDF 文档

yield return与IronPDF的交集

现在,让我们探讨yield return语句——一种用于惰性求值和高效迭代的强大工具,是否可以与IronPDF无缝集成。

考虑一个需要使用yield return生成包含项列表的PDF文档的场景。 您可以利用yield语句动态生成内容,然后使用IronPDF将该内容转换为PDF。 以下代码片段利用yield语句生成一个PDF文档,以动态控制PDF内容:

class Program
{
    static void Main(string [] args)
    {
        public IEnumerable<string> GenerateDynamicContent()
        {
            yield return "Item 1";
            yield return "Item 2";
            yield return "Item 3";
        }

        // Usage
        var dynamicContent = GenerateDynamicContent();
        var dynamicPdfContent = $@"
            <html>
            <body>
                <h1>List of Items</h1>
                <ul>
                    {string.Join("", dynamicContent.Select(item => $"<li>{item}</li>"))}
                </ul>
            </body>
            </html>
        ";

        // Create a new PDF document with dynamically generated content
        var dynamicPdfDocument = new IronPdf.ChromePdfRenderer();
        dynamicPdfDocument.RenderHtmlAsPdf(dynamicPdfContent).SaveAs("C:/DynamicItems.pdf");
    }
}
class Program
{
    static void Main(string [] args)
    {
        public IEnumerable<string> GenerateDynamicContent()
        {
            yield return "Item 1";
            yield return "Item 2";
            yield return "Item 3";
        }

        // Usage
        var dynamicContent = GenerateDynamicContent();
        var dynamicPdfContent = $@"
            <html>
            <body>
                <h1>List of Items</h1>
                <ul>
                    {string.Join("", dynamicContent.Select(item => $"<li>{item}</li>"))}
                </ul>
            </body>
            </html>
        ";

        // Create a new PDF document with dynamically generated content
        var dynamicPdfDocument = new IronPdf.ChromePdfRenderer();
        dynamicPdfDocument.RenderHtmlAsPdf(dynamicPdfContent).SaveAs("C:/DynamicItems.pdf");
    }
}
Friend Class Program
	Shared Sub Main(ByVal args() As String)
'INSTANT VB TODO TASK: Local functions are not converted by Instant VB:
'		public IEnumerable(Of string) GenerateDynamicContent()
'		{
'			yield Return "Item 1";
'			yield Return "Item 2";
'			yield Return "Item 3";
'		}

		' Usage
		Dim dynamicContent = GenerateDynamicContent()
, String.Join(TangibleTempVerbatstring.Format(mDoubleQuote, dynamicContent.Select(Function(item) $TangibleTempVerbatimCloseTag"<li>{item}</li>")), TangibleStringInterpolationMarker) var dynamicPdfContent = $"TangibleTempVerbatimOpenTagTangibleTempVerbatimStringLiteralLineJoin            <html>TangibleTempVerbatimStringLiteralLineJoin            <body>TangibleTempVerbatimStringLiteralLineJoin                <h1>List of Items</h1>TangibleTempVerbatimStringLiteralLineJoin                <ul>TangibleTempVerbatimStringLiteralLineJoin                    {0}ignoreignoreignoreignoreignore</ul></body></html>"

		' Create a new PDF document with dynamically generated content
		Dim dynamicPdfDocument = New IronPdf.ChromePdfRenderer()
		dynamicPdfDocument.RenderHtmlAsPdf(dynamicPdfContent).SaveAs("C:/DynamicItems.pdf")
	End Sub
End Class
$vbLabelText   $csharpLabel

在此示例中,GenerateDynamicContent 方法使用 yield return 来提供一系列动态项。 然后将生成的内容纳入 HTML 结构,并由 IronPDF 用于创建 PDF 文档。

C# Yield Return(对开发者的工作原理):图 2 - 来自前述代码的输出 PDF

结论

总之,yield return 是 C# 中一个强大而优雅的特性,它改变了你处理迭代的方式。 它能够支持懒惰评估、通过有状态迭代处理复杂场景并创建无限序列,是您编程工具包中的重要工具。 无论您是在处理大型数据集还是在实现复杂算法,yield return 都能让您编写更高效和更具表现力的代码。

yield return促进高效和按需生成内容时,IronPDF可以无缝地将这些内容转换为专业的PDF文档。 无论您是动态创建列表、报告还是其他任何文档,这种协同作用都能让您将 C# 文档生成能力提升到新的高度。 拥抱这对充满潜力的动态组合,让您的PDF凭借动态且高效生成的内容大放异彩!

IronPDF 提供免费试用,其完整功能与商业模式一样。 了解更多关于IronPDF 许可证,起价为$749。

Chipego
软件工程师
Chipego 拥有出色的倾听技巧,这帮助他理解客户问题并提供智能解决方案。他在 2023 年加入 Iron Software 团队,此前他获得了信息技术学士学位。IronPDF 和 IronOCR 是 Chipego 主要专注的两个产品,但他对所有产品的了解每天都在增长,因为他不断找到支持客户的新方法。他喜欢 Iron Software 的合作氛围,公司各地的团队成员贡献他们丰富的经验,以提供有效的创新解决方案。当 Chipego 离开办公桌时,你经常可以发现他在看书或踢足球。
< 前一页
C# REPL(它对开发者的工作原理)
下一步 >
C# 数组排序(开发人员指南)