我正在阅读此博客:Pipes and filters pattern
我对这段代码感到困惑:
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());?这段代码似乎是空话。
最佳答案
首先考虑这个:
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
链传递,每个元素都对它们执行一些操作。最终结果被丢弃,因此只有操作的副作用是有趣的——例如写入控制台或记录到文件。这本来是编写最后两行的一种更简单的方法:
foreach (T t in current) {}
另一件需要注意的事情是,启动进程的初始列表是一个空列表,因此为了使其有意义,必须在第一个操作中创建 T 的一些实例。在本文中,这是通过要求用户从控制台输入来完成的。
关于c# - 帮助我理解 c# 中的代码片段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2693461/