在 C# 9 中使用 foreach 擴充套件

2023-01-06 12:01:25

在 C# 9 中,foreach 迴圈可以使用擴充套件方法。在本文中,我們將通過例子回顧 C# 9 中如何擴充套件 foreach 迴圈。

程式碼演示

下面是一個對樹形結構進行深度優先遍歷的範例程式碼:

using System;
using System.Collections.Generic;

namespace Example
{
    class TreeNode
    {
        public int Value { get; set; }
        public List<TreeNode> Children { get; set; }

        public TreeNode(int value)
        {
            Value = value;
            Children = new List<TreeNode>();
        }
    }

    static class TreeExtensions
    {
        public static IEnumerable<TreeNode> DepthFirst(this TreeNode root)
        {
            yield return root;
            foreach (var child in root.Children.SelectMany(DepthFirst))
            {
                yield return child;
            }
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var root = new TreeNode(1);
            root.Children.Add(new TreeNode(2));
            root.Children.Add(new TreeNode(3));
            root.Children[0].Children.Add(new TreeNode(4));
            root.Children[0].Children.Add(new TreeNode(5));

            foreach (var node in root.DepthFirst())
            {
                Console.WriteLine(node.Value);
            }
            // Outputs: 1 2 4 5 3
        }
    }
}

在這個範例程式碼中,我們在 TreeNode 類中定義了一個值屬性和一個儲存子節點的列表屬性。我們還在 TreeExtensions 類中定義了一個 DepthFirst 擴充套件方法,該方法使用 yield return 語句來返回樹形結構的深度優先遍歷結果。

在 Main 方法中,我們建立了一個樹形結構,然後使用 foreach 迴圈來遍歷樹形結構的深度優先遍歷結果。

之所以使用擴充套件方法往往是因為,我們可以在不修改 TreeNode 類的情況下,為 TreeNode 類新增新的功能。

那麼接下來我們希望在 C# 9 中預設為 TreeNode 類新增 DepthFirst 行為,這樣我們就可以直接使用 foreach 迴圈來遍歷樹形結構的深度優先遍歷結果了。

C# 9 中的 foreach 擴充套件

在 C# 9 中,我們可以使用 foreach 擴充套件來實現上面的需求。我們只需要在 TreeNode 類中新增一個 GetEnumerator 方法,該方法返回一個實現了 IEnumerable 介面的物件即可。

static class TreeExtensions
{
    public static IEnumerable<TreeNode> DepthFirst(this TreeNode root)
    {
        yield return root;
        foreach (var child in root.Children.SelectMany(DepthFirst))
        {
            yield return child;
        }
    }

    public static IEnumerator<TreeNode> GetEnumerator(this TreeNode root)
    {
        return root.DepthFirst().GetEnumerator();
    }
}

在上面的程式碼中,我們在 TreeNode 類中新增了一個 GetEnumerator 方法,該方法返回一個實現了 IEnumerable 介面的物件。這個物件就是我們在 DepthFirst 方法中使用 yield return 語句返回的結果。

現在我們可以直接使用 foreach 迴圈來遍歷樹形結構的深度優先遍歷結果了。

foreach (var node in root)
{
    Console.WriteLine(node.Value);
}

總結

在 C# 9 中,我們可以使用 foreach 擴充套件來為類新增新的行為。在上面的範例程式碼中,我們為 TreeNode 類新增了 DepthFirst 行為,這樣我們就可以直接使用 foreach 迴圈來遍歷樹形結構的深度優先遍歷結果了。

參考資料

  • Extension GetEnumerator support for foreach loops[1]
  • 本文作者: newbe36524
  • 本文連結: https://www.newbe.pro/ChatAI/0x013-Extension-foreach-in-csharp-9/
  • 版權宣告: 本部落格所有文章除特別宣告外,均採用 BY-NC-SA 許可協定。轉載請註明出處!

參考資料

[1]

Extension GetEnumerator support for foreach loops: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-9.0/extension-getenumerator?WT.mc_id=DX-MVP-5003606