简体   繁体   English

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

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

I am reading this blog: Pipes and filters pattern 我正在阅读这篇博客: 管道和过滤器模式

I am confused by this code snippet: 我对这段代码感到困惑:

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());
    }
}

what is the purpose of this statement: while (enumerator.MoveNext()); 这句话的目的是什么: while(enumerator.MoveNext()); ? seems this code is a noop. 似乎这个代码是noop。

First consider this: 首先考虑一下:

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

This code appears to be creating nested enumerables, each of which takes elements from the previous, applies some operation to them, and passes the result to the next. 此代码似乎是创建嵌套的枚举,每个枚举都使用前一个元素,对它们应用一些操作,并将结果传递给下一个。 But it only constructs the enumerables. 但它只构造了枚举。 Nothing actually happens yet. 什么都没发生呢。 It's just ready to go, stored in the variable current . 它已经准备就绪,存储在可变current There are lots of ways to implement IOperation.Execute but it could be something like this. 有很多方法可以实现IOperation.Execute但它可能是这样的。

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

Another option suggested in the article is a sort: 本文中建议的另一种选择是:

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);
}

Now look at this: 现在看看这个:

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

This actually causes the chain of operations to be performed. 这实际上导致执行操作链。 When the elements are requested from the enumeration, it causes elements from the original enumerable to be passed through the chain of IOperations , each of which performs some operation on them. 当从枚举中请求元素时,它会使原始枚举中的元素通过IOperations链传递,每个IOperations都对它们执行一些操作。 The end result is discarded so only the side-effect of the operation is interesting - such as writing to the console or logging to a file. 最终结果被丢弃,因此只有操作的副作用很有趣 - 例如写入控制台或记录到文件。 This would have been a simpler way to write the last two lines: 这可能是编写最后两行的简单方法:

foreach (T t in current) {}

Another thing to observe is that the initial list that starts the process is an empty list so for this to make sense some instances of T have to be created inside the first operation. 另一件需要注意的事情是,启动进程的初始列表是一个空列表,因此为了理解这一点,必须在第一个操作中创建一些T实例。 In the article this is done by asking the user for input from the console. 在本文中,这是通过询问用户从控制台输入来完成的。

In this case, the while (enumerator.MoveNext()); 在这种情况下, while (enumerator.MoveNext()); is simply evaluating all the items that are returned by the final IOperation<T> . 只是评估最终IOperation<T>返回的所有项目。 It looks a little confusing, but the empty List<T> is only created in order to supply a value to the first IOperation<T> . 它看起来有点令人困惑,但只创建空List<T>以便为第一个IOperation<T>提供值。

In many collections this would do exaclty nothing as you suggest, but given that we are talking about the pipes and filters pattern it is likely that the final value is some sort of iterator that will cause code to be executed. 在许多集合中,这可能会像你建议的那样做得很多,但鉴于我们正在谈论管道和过滤器模式,最终的值可能是某种迭代器会导致代码被执行。 It could be something like this, for example (assuming that is an integer): 它可能是这样的,例如(假设它是一个整数):

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

So calling MoveNext() for each item on the IEnumerator<int> returned by this iterator will return each of the values (which are ignored in the while loop) but also output each of the values to the console. 因此,为此迭代器返回的IEnumerator<int>上的每个项调用MoveNext()将返回每个值(在while循环中被忽略),但也会将每个值输出到控制台。

Does that make sense? 那有意义吗?

while (enumerator.MoveNext());

Inside the current block of code, there is no affect (it moves through all the items in the enumeration). 在当前代码块内,没有任何影响(它遍历枚举中的所有项)。 The displayed code doesn't act on the current element in the enumeration. 显示的代码不会对枚举中的当前元素起作用。 What might be happening is that the MoveNext() method is moving to the next element, and it is doing something to the objects in the collection (updating an internal value, pull the next from the database etc.). 可能发生的事情是MoveNext()方法正在移动到下一个元素,它正在对集合中的对象执行某些操作(更新内部值,从数据库中提取下一个等)。 Since the type is List<T> this is probably not the case, but in other instances it could be. 由于类型是List<T>这可能不是这种情况,但在其他情况下可能是这种情况。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM