帮我理解c#中的代码片段

Ben*_*nny 10 c# code-snippets

我正在阅读这篇博客:管道和过滤器模式

我对这段代码感到困惑:

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());
    }
}
Run Code Online (Sandbox Code Playgroud)

这句话的目的是什么: while(enumerator.MoveNext()); ?似乎这个代码是noop.

Mar*_*ers 7

首先考虑一下:

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

此代码似乎是创建嵌套的枚举,每个枚举都使用前一个元素,对它们应用一些操作,并将结果传递给下一个.但它只构造了枚举.什么都没发生呢.它只是准备好了,存储在变量中current.有很多方法可以实现,IOperation.Execute但它可能是这样的.

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

本文中建议的另一种选择是:

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);
}
Run Code Online (Sandbox Code Playgroud)

现在看看这个:

IEnumerator<T> enumerator = current.GetEnumerator();
while (enumerator.MoveNext());
Run Code Online (Sandbox Code Playgroud)

这实际上导致执行操作链.当从枚举中请求元素时,它会使原始可枚举中的元素通过链传递IOperations,每个元素对它们执行一些操作.最终结果被丢弃,因此只有操作的副作用很有趣 - 例如写入控制台或记录到文件.这可能是编写最后两行的简单方法:

foreach (T t in current) {}
Run Code Online (Sandbox Code Playgroud)

另一件需要注意的事情是,启动进程的初始列表是一个空列表,因此为了理解这一点,必须在第一个操作中创建一些T实例.在本文中,这是通过询问用户从控制台输入来完成的.