Эти два не эквивалентны. Семантика отсрочки выполнения между двумя методами Bar
различна. Foo.Bar
преобразует Sequence
в значение IEnumerable
, когда вы вызываете Bar
. Foo2.Bar2
преобразует Sequence
в значение этой переменной , когда вы перечисляете последовательность, возвращаемую Bar2
.
Мы можем написать достаточно простую программу, чтобы наблюдать различия здесь.
//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;
}
}
Теперь давайте попробуем сравнить эти два метода, чтобы увидеть, как они работают:
var query = foo.IteratorBlock();
var query2 = foo.NoIteratorBlock();
Console.WriteLine("---");
query.Count();
query.Count();
query2.Count();
query2.Count();
Это распечатает:
Я повторяю Sequence без блока итератора
---
Я повторяю Sequence в блоке итератора
Я повторяю Sequence в блоке итератора
Здесь мы видим, что побочные эффекты блока без итератора возникают когда вызывается сам метод, а побочные эффекты блока итератора в этот момент не проявляются. Затем, позже, каждый раз, когда мы повторяем блок без итератора, это вообще не вызывает побочных эффектов, но блок итератора вызывает побочные эффекты каждый раз при повторении запроса.
person
Servy
schedule
26.08.2014