The IEnumerable interface is a very important interface in the C# development process, and it is necessary to understand its features and usage. This article will familiarize yourself with its simple usage through 10 small examples.

All source code

The following are 10 small examples, and the description of the response is marked in the comment.

Each named after the beginning of TXX is an example. It is recommended to read from top to bottom.

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]
//IEnumerable example:Loop to get even numbers
        public void T01()
        {
            // Create a collection to store the final result
            var result = new List<int>();
            for (var i = 0; i <= 10; i++)
            {
                // If it is even, put the numbers in the collection
                if (i % 2 == 0)
                {
                    result.Add(i);
                }
            }
 
            // Asserting the final result
            result.Should().Equal(0, 2, 4, 6, 8, 10);
        }
 
        [Fact]
//IEnumerable example:Ordinary Enumerable
        public void T02()
        {
            // Get even Enumerable objects by static methods
            var result = GetNumber(10);
 
            // Assertive result
            result.Should().Equal(0, 2, 4, 6, 8, 10);
 
            /**
             * This type of writing is less of a set creation than T01, which is usually a better performance.
             */
        }
 
        /// <summary>
        /// Get an even number less than or equal to 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)
                {
                    // Use yield return to return the result of each iteration
                    yield return i;
                }
            }
        }
 
        [Fact]
//IEnumerable example:Local function
        public void T02()
        {
            // Get results by local function
            var result = GetNumber(10);
 
            // Assertive result
            result.Should().Equal(0, 2, 4, 6, 8, 10);
 
            /**
             * Get the Enumerable object using a local function.
              * The effect here is similar to the static method.
              * Native functions are syntax features that C# 7.0 only supports.
              * See the details of the local function.: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]
//IEnumerable example:Separation condition
        public void T03()
        {
            /**
             * Use Where to filter results
              * This approach separates the logic of "self-increasing" logic and "judging is even"
             */
            var result = GetNumber(10)
                .Where(x => x % 2 == 0);
 
            result.Should().Equal(0, 2, 4, 6, 8, 10);
 
            // Iterative time is only a self-incrementing operation
            IEnumerable<int> GetNumber(int max)
            {
                for (var i = 0; i <= max; i++)
                {
                    yield return i;
                }
            }
        }
 
        [Fact]
//IEnumerable example:Linq produces values
        public void T04()
        {
            // The system has a built-in method to get the self-incrementing sequence of numbers, so it can be simplified
            var result = Enumerable
                .Range(0, 11)
                .Where(x => x % 2 == 0);
 
            result.Should().Equal(0, 2, 4, 6, 8, 10);
        }
 
        [Fact]
//IEnumerable example:Output 233
        public void T05()
        {
            // Output 3 numbers 233
            var result = Get233().Take(3);
            result.Should().Equal(2, 3, 3);
 
            // Output 5 digits 23333
            result = Get233().Take(5);
            result.Should().Equal(2, 3, 3, 3, 3);
 
            IEnumerable<int> Get233()
            {
                // First output 2
                yield return 2;
                while (true)
                {
                    // Output after 3
                    yield return 3;
                }
            }
 
            /**
             * It is worth noting that while(true) does not cause the program to fall into an infinite loop.
              * Because yield return is performed on an as-demand basis.
             
             */
        }
 
        [Fact]
//IEnumerable example:Get 10 random numbers less than 50
        public void T06()
        {
            /**
             * Filter the numbers in the random number less than 50 and get only 10 of them.
             */
            var result = GetRandom()
                .Where(x => x < 50)
                .Take(10)
                .ToArray();
 
            // assertion
            result.Should().HaveCount(10);
            result.All(x => x < 50).Should().BeTrue();
 
            IEnumerable<int> GetRandom()
            {
                var random = new Random();
                // Continuously output 0-100 random numbers
                while (true)
                {
                    yield return random.Next(0, 100);
                }
            }
        }
 
        [Fact]
//IEnumerable example:Automatically complement random numbers
        public void T07()
        {
            // Get 3 numbers
            var result1 = GetData().Take(3);
 
            // 3 numbers are 0, 1, 2
            result1.Should().Equal(0, 1, 2);
 
            // Get 10 numbers
            var result2 = GetData().Take(10).ToArray();
 
            // The first 5 digits are 0, 1, 2, 3, 4
            result2.Take(5).Should().Equal(0, 1, 2, 3, 4);
            // Numbers starting with the 5th are greater than 10
            result2.Skip(5).Take(5).Should().Match(x => x.All(a => a > 10));
 
            /**
             * Get a set of data, the first 5 digits are 0, 1, 2, 3, 4 . Continue to get later is a random number
             */
            IEnumerable<int> GetData()
            {
                var staticData = new[] {0, 1, 2, 3, 4};
                foreach (var i in staticData)
                {
                    yield return i;
                }
 
                var random = new Random();
                // Continuously output 10-100 random numbers
                while (true)
                {
                    yield return random.Next(10, 100);
                }
            }
        }
 
        [Fact]
//IEnumerable example:Conditional to cycle
        public void T08()
        {
            var book1 = GetReadingBook(DateTime.Parse("2019-08-30")).First();
            book1.Should().Be("Every Friday is a happy day");
 
            var book2 = GetReadingBook(DateTime.Parse("2016-02-29")).First();
            book2.Should().Be("Once every four years");
 
            var book3 = GetReadingBook(DateTime.Parse("2019-09-01")).First();
            book3.Should().BeSameAs("Month boss software development small coups thirty-two");
 
            // Get the name of the book you need to read at a given time
            IEnumerable<string> GetReadingBook(DateTime time)
            {
                // 周五
                if (time.DayOfWeek == DayOfWeek.Friday)
                {
                    yield return "Every Friday is a happy day";
                }
 
                // 2月29日
                if (time.Date.Month == 2 && time.Date.Day == 29)
                {
                    yield return "Once every four years";
                }
 
                // Read other books at other times
                yield return "Month boss software development small coups thirty-two";
            }
        }
 
        [Fact]
//IEnumerable example:Get a link string
        public void T09()
        {
            // Get a currently available link string
            var conn = GetConnectionString().FirstOrDefault();
            conn.Should().Be("Source=;UID=x;Password=******");
 
            IEnumerable<string> GetConnectionString()
            {
                // Get the link string from a file
                var connFilename = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "conn.txt");
                if (File.Exists(connFilename))
                {
                    var fileContent = File.ReadAllText(connFilename);
                    yield return fileContent;
                }
 
                // Read the link string from the configuration file
                var dbConnectionString = ConfigurationManager.ConnectionStrings["db"]?.ConnectionString;
                if (!string.IsNullOrEmpty(dbConnectionString))
                {
                    yield return dbConnectionString;
                }
 
                // Return the default string
                yield return "Source=;UID=x;Password=******";
            }
        }
 
        [Fact]
//IEnumerable example:Test network connection
        public async Task T10()
        {
            var httpClient = new HttpClient();
            try
            {
                await Task.WhenAll(SendRequests());
                _testOutputHelper.WriteLine("The current network connection is normal.");
            }
            catch (Exception e)
            {
                _testOutputHelper.WriteLine("The current network is not working properly, please check the network connection.");
            }
 
            IEnumerable<Task> SendRequests()
            {
                yield return Task.Run(() => httpClient.GetAsync("http://www.codecoder.top"));
                yield return Task.Run(() => httpClient.GetAsync("http://www.bing.com"));
                yield return Task.Run(() => httpClient.GetAsync("http://www.google.com"));
            }
        }
    }
}

source description

The project uses netcore 2.2 as the target framework, so you need to install the netcore 2.2 SDK to run.