在 C# 中使用枚举器

发布日期:2026-07-14 19:04:05   来源 : 杭州电子商务研究院    浏览量 :5
杭州电子商务研究院 发布日期:2026-07-14 19:04:05  
5

介绍

自从程序员开始编程以来,就有一些基本的数据结构允许列出或收集特定的项目。这些项目通常被传递给其他函数进行处理或写入远程位置。这些基本数据结构(如列表)具有非常成问题的属性。假设您想将一个包含 10 个项目的列表传递给另一个函数。整数的大小为 32 位(4 字节),并将其乘以您要传输的数量。在本例中,它只有 40 字节。随着您将越来越多的项目堆积到列表中,它的大小会以线性方式增长。100 个项目意味着 400 字节;1 百万个项目会消耗 GB 的内存。并非所有系统都配备了处理这种情况的资源。yield return语句以及枚举器和可枚举器的概念可以提供帮助。

枚举器和可枚举器

有一个名为反射器的好用工具,当您使用此技术时,可以使用它来查看生成的类。

当我们谈论枚举器时,我们只是谈论枚举时使用的句柄。它指向当前元素,并可以移动到指向下一个元素。

当我们谈论可枚举时,我们只是在谈论实现一些基本协议的类或数据类型,这些协议允许枚举器遍历其项目。

简单退货声明

此函数接受一个参数,该参数指示应返回多少个偶数。

      public static List<int> EvenNumbers(int max)
	{
    	var retList = new List<int>();
        int i = 0;
        while (retList.Count < max)
        	{
        		retList.Add(i += 2);
            }
    	return retList;
	}
    

这是一个简单的例子,但如果我们检查代码,就会发现瓶颈。随着我们增加max参数,我们返回的列表变得越来越大。这是因为我们一次返回整个列表,并且在保留最大偶数的情况下执行此操作。

调用此 for 循环打印元素显示应用程序消耗了近 3GB 的内存。

      foreach (int i in EvenNumbers(1000000000))
	{
    	Console.WriteLine($"Number {i}");
	}
    

我想你现在应该知道我在想什么。一定有更好的方法。我们希望防止我们的应用程序占用过多的内存。

输入收益率

Yield return语句会告诉我们的编译器,此函数每次调用只能返回一个元素,并且会暂停,直到请求另一个元素。当不再需要其他元素时,它就会被中断,而不会运行到结束(即耗尽)

      public static IEnumerable<int> OddNumbers(int max)
	{
    	int i = 1;
        while (i < (max * 2))
            {
                yield return i;
                i += 2;
            }            
	}
    

执行以下语句:

      foreach (int i in OddNumbers(1000000000))
	{
    	Console.WriteLine($"Number {i}");
	}
    

注意枚举器yield return语句的强大功能。在执行过程中,RAM使用量保持在约10MB左右,这比老式的返回整个列表方法有了很大的改进,最终结果基本相同。一个显着的区别是它返回奇数,而不是像其他函数那样返回偶数

要么接受,要么放弃

当我们使用可枚举数据类型时,我们可以应用一个函数从我们的项目中获取特定数量的元素。

      foreach (int i in OddNumbers(100).Take(10))
    {
		Console.WriteLine($"Number {i}");
	}
    

这种方法仅给我们提供从可枚举数据类型排序的 100 个奇数的前 10 个元素。

整个应用程序

我想为您提供整个控制台应用程序,以便您可以进行试用。

请注意,为了转换功能,您需要在应用程序顶部使用以下两个额外的语句。

      using System.Collections.Generic;
using System.Linq;
    

这些将为您提供“Take”函数以及将OddNumbers函数的返回类型设置为IEnumerable 的能力。

如果没有这个,您将看到一个错误,指出编译器无法找到适当的类型/函数。

      using System;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleApp
{
    class Program
    {
        public static IEnumerable<int> OddNumbers(int max)
        {
            int i = 1;
            while (i < (max * 2))
            {
                yield return i;
                i += 2;
            }            
        }
        public static List<int> EvenNumbers(int max)
        {
            var retList = new List<int>();
            int i = 0;
            while (retList.Count < max)
            {
                retList.Add(i += 2);
            }
            return retList;
        }
        static void Main(string[] args)
        {
            //The efficient Enumerable version.
            foreach (int i in OddNumbers(100).Take(10))
            {
                Console.WriteLine($"Number {i}");
            }
            // The memory hungry beast
            foreach(int i in EvenNumbers(100000000))
            {
                Console.WriteLine($"Number: {i}");
            }
            Console.Read();
        }
    }
}
    

结论

我们常常误以为,通过使用功能越来越强大的计算机,我们可以忽略编写高效的代码。可枚举数据类型为您提供了创建应用程序的方法,这些应用程序可以处理大量数据,并防止它们耗尽您的所有系统资源。这种技术在整个行业中被广泛使用,它可以成为您编程工具集中非常有效的方法。

以上内容来自杭州电子商务研究院推送
关注
关于我们
热门推荐
合作伙伴
免责声明:本站部分资讯来源于网络,如有侵权请及时联系客服,我们将尽快处理
Copyright © 2025-2027 ToB产业网址导航 公安备案 浙公网安备33010602013138号 浙ICP备16025413号-9
支持 反馈 关注 数据