簡體   English   中英

幫我理解c#中的代碼片段

[英]Help me understand the code snippet in c#

我正在閱讀這篇博客: 管道和過濾器模式

我對這段代碼感到困惑:

public class Pipeline<T>
{
    private readonly List<IOperation<T>> operations = new List<IOperation<T>>();

    public Pipeline<T> Register(IOperation<T> operation)
    {
        operations.Add(operation);
        return this;
    }

    public void Execute()
    {
        IEnumerable<T> current = new List<T>();
        foreach (IOperation<T> operation in operations)
        {
            current = operation.Execute(current);
        }
        IEnumerator<T> enumerator = current.GetEnumerator();
        while (enumerator.MoveNext());
    }
}

這句話的目的是什么: while(enumerator.MoveNext()); 似乎這個代碼是noop。

首先考慮一下:

IEnumerable<T> current = new List<T>();
foreach (IOperation<T> operation in operations)
{
    current = operation.Execute(current);
}

此代碼似乎是創建嵌套的枚舉,每個枚舉都使用前一個元素,對它們應用一些操作,並將結果傳遞給下一個。 但它只構造了枚舉。 什么都沒發生呢。 它已經准備就緒,存儲在可變current 有很多方法可以實現IOperation.Execute但它可能是這樣的。

IEnumerable<T> Execute(IEnumerable<T> ts)
{
    foreach (T t in ts)
        yield return this.operation(t); // Perform some operation on t.
}

本文中建議的另一種選擇是:

IEnumerable<T> Execute(IEnumerable<T> ts)
{
    // Thank-you LINQ!
    // This was 10 lines of non-LINQ code in the original article.
    return ts.OrderBy(t => t.Foo);
}

現在看看這個:

IEnumerator<T> enumerator = current.GetEnumerator();
while (enumerator.MoveNext());

這實際上導致執行操作鏈。 當從枚舉中請求元素時,它會使原始枚舉中的元素通過IOperations鏈傳遞,每個IOperations都對它們執行一些操作。 最終結果被丟棄,因此只有操作的副作用很有趣 - 例如寫入控制台或記錄到文件。 這可能是編寫最后兩行的簡單方法:

foreach (T t in current) {}

另一件需要注意的事情是,啟動進程的初始列表是一個空列表,因此為了理解這一點,必須在第一個操作中創建一些T實例。 在本文中,這是通過詢問用戶從控制台輸入來完成的。

在這種情況下, while (enumerator.MoveNext()); 只是評估最終IOperation<T>返回的所有項目。 它看起來有點令人困惑,但只創建空List<T>以便為第一個IOperation<T>提供值。

在許多集合中,這可能會像你建議的那樣做得很多,但鑒於我們正在談論管道和過濾器模式,最終的值可能是某種迭代器會導致代碼被執行。 它可能是這樣的,例如(假設它是一個整數):

public class WriteToConsoleOperation : IOperation<int>
{
    public IEnumerable<int> Execute(IEnumerable<int> ints)
    {
        foreach (var i in ints)
        {
            Console.WriteLine(i);
            yield return i;
        }
     }
}

因此,為此迭代器返回的IEnumerator<int>上的每個項調用MoveNext()將返回每個值(在while循環中被忽略),但也會將每個值輸出到控制台。

那有意義嗎?

while (enumerator.MoveNext());

在當前代碼塊內,沒有任何影響(它遍歷枚舉中的所有項)。 顯示的代碼不會對枚舉中的當前元素起作用。 可能發生的事情是MoveNext()方法正在移動到下一個元素,它正在對集合中的對象執行某些操作(更新內部值,從數據庫中提取下一個等)。 由於類型是List<T>這可能不是這種情況,但在其他情況下可能是這種情況。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM