Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何将这个迭代器块转换为函数更改?_C#_Iterator_Yield Return_Deferred Execution - Fatal编程技术网

C# 如何将这个迭代器块转换为函数更改?

C# 如何将这个迭代器块转换为函数更改?,c#,iterator,yield-return,deferred-execution,C#,Iterator,Yield Return,Deferred Execution,给定以下代码段: public class Foo { public IEnumerable<string> Sequence { get; set; } public IEnumerable<string> Bar() { foreach (string s in Sequence) yield return s; } } 公共类Foo { 公共IEnumerable序列{get;set;} 公共

给定以下代码段:

public class Foo
{
    public IEnumerable<string> Sequence { get; set; }
    public IEnumerable<string> Bar()
    {
        foreach (string s in Sequence)
            yield return s;
    }
}
公共类Foo
{
公共IEnumerable序列{get;set;}
公共IEnumerable Bar()
{
foreach(序列中的字符串s)
收益率;
}
}
以下代码段在语义上是等效的,还是不同的?如果是不同的,它们的功能如何不同

public class Foo2
{
    public IEnumerable<string> Sequence { get; set; }
    public IEnumerable<string> Bar2()
    {
        return Sequence;
    }
}
公共类Foo2
{
公共IEnumerable序列{get;set;}
公共IEnumerable Bar2()
{
返回序列;
}
}

这个问题的灵感来源于对类似情况提出不同的问题。

这两个问题并不等同。两种
Bar
方法之间执行延迟的语义不同<当您调用
Bar
时,code>Foo.Bar将
Sequence
计算为
IEnumerable
Foo2.Bar2
在枚举由
Bar2
返回的序列时,将
Sequence
计算为该变量中的值

我们可以编写一个足够简单的程序来观察这里的差异

//Using iterator block
var foo = new Foo();
foo.Sequence = new[] { "Old" };
var query = foo.Bar();
foo.Sequence = new[] { "New" };
Console.WriteLine(string.Join(" ", query));

//Not using iterator block
var foo2 = new Foo2();
foo2.Sequence = new[] { "Old" };
var query2 = foo2.Bar2();
foo2.Sequence = new[] { "New" };
Console.WriteLine(string.Join(" ", query2));
这将打印出:

新的
旧的

在这种特殊情况下,我们的
Bar
方法也没有副作用。如果它这样做了,那么理解程序所具有的语义以及它应该具有的内容就不会显得更重要了。例如,让我们修改这两种方法,使其具有一些可观察到的副作用:

public class Foo
{
    public IEnumerable<string> Sequence { get; set; }
    public IEnumerable<string> IteratorBlock()
    {
        Console.WriteLine("I'm iterating Sequence in an iterator block");
        foreach (string s in Sequence)
            yield return s;
    }
    public IEnumerable<string> NoIteratorBlock()
    {
        Console.WriteLine("I'm iterating Sequence without an iterator block");
        return Sequence;
    }
}
这将打印出:

我正在迭代没有迭代器块的序列
---
我正在迭代迭代器块中的序列
我正在迭代迭代器块中的序列


在这里,我们可以看到,非迭代器块的副作用发生在调用方法本身时,迭代器块的副作用不会在该时间点发生。然后,稍后,每次我们迭代非迭代器块时,它根本不会产生副作用,但每次迭代查询时,迭代器块都会产生副作用。

恭喜,到目前为止,您是整个网络上自我应答反转徽章的骄傲持有者。无需粗鲁,看起来他们提出了一个合理的问题,然后找到了答案。@quantumpotato他没有粗鲁,只是指出了一些他们认为有趣的事情(我也觉得很幽默)。还请注意,我同时发布了问题和答案;我在写问题之前就知道答案了。我之所以写这篇文章,是因为其他人对它有误解(在链接的问题中),所以我发布了这个问题,以避免对这个主题的解释(与那个问题无关)分散对实际问题的注意力。这个问题呢?试图理解投票的逻辑确实很有趣。做得好,回答者,他们似乎在说,因为他们如此清楚地回答了这个愚蠢的问题。你显然比那个愚蠢的提问者聪明得多。
var query = foo.IteratorBlock();
var query2 = foo.NoIteratorBlock();
Console.WriteLine("---");
query.Count();
query.Count();
query2.Count();
query2.Count();