Мне пришлось почти катастрофически узнать, насколько круто / опасно yield
, когда я решил заставить анализатор нашей компании лениво читать входящие данные. К счастью, только одна из немногих наших реализующих функций фактически использовала ключевое слово yield. Потребовалось несколько дней, чтобы понять, что он тихо вообще ничего не делал.
Ключевое слово yield будет настолько ленивым, насколько это возможно, в том числе вообще пропустит метод, если вы не включите его для работы с чем-то вроде .ToList()
или .FirstOrDefault()
или .Any()
Ниже представлены две вариации: одна с использованием ключевого слова, а вторая с возвратом прямого списка. Один даже не потрудится выполнить, а другой выполнит, даже если они кажутся одинаковыми.
public class WhatDoesYieldDo
{
public List<string> YieldTestResults;
public List<string> ListTestResults;
[TestMethod]
public void TestMethod1()
{
ListTest();
Assert.IsTrue(ListTestResults.Any());
YieldTest();
Assert.IsTrue(YieldTestResults.Any());
}
public IEnumerable<string> YieldTest()
{
YieldTestResults = new List<string>();
for (var i = 0; i < 10; i++)
{
YieldTestResults.Add(i.ToString(CultureInfo.InvariantCulture));
yield return i.ToString(CultureInfo.InvariantCulture);
}
}
public IEnumerable<string> ListTest()
{
ListTestResults = new List<string>();
for (var i = 0; i < 10; i++)
{
ListTestResults.Add(i.ToString(CultureInfo.InvariantCulture));
}
return ListTestResults;
}
}
Мораль истории: убедитесь, что если у вас есть метод, который возвращает IEnumerable, и вы используете yield
в этом методе, у вас есть что-то, что будет перебирать результаты, или метод вообще не будет выполняться. *