Взгляните на этот пример:
void Main()
{
IEnumerable<int> items = Test2();
foreach (var item in items)
{
Console.WriteLine(item);
}
var newitems = new StringBuilder();
foreach (var item in items)
{
newitems.Append(item);
}
}
IEnumerable<int> Test2()
{
Console.WriteLine("Test2 called");
return GetEnum();
}
IEnumerable<int> GetEnum()
{
for(var i = 0; i < 5; i ++)
{
Console.WriteLine("Doing work...");
Thread.Sleep(50); //Download some information from a website, or from a database
yield return i;
}
}
Представьте себе, что return GetEnum();
был return new int[] { 1, 2, 3 }
Теперь, с массивами, итерация их несколько раз, не обязательно плохо. В вашем случае вы можете выполнять работу в одном цикле, но это не причина, по которой вас предупреждает resharper. Он предупреждает вас из-за возможности, что Test2()
возвращает ленивый перечислимый, который действительно работает каждый раз, когда он повторяется.
Если запустить приведенный выше код, вы получите этот результат:
Test2 called
Doing work...
0
Doing work...
1
Doing work...
2
Doing work...
3
Doing work...
4
Doing work...
Doing work...
Doing work...
Doing work...
Doing work...
Обратите внимание, что Test2
сам вызывается только один раз, но перечислимы повторяется дважды (и работа выполняется в два раза!).
Вы можете избежать этого, написав:
var items = Test2().ToList();
Который сразу же оценить перечислимы и поместить его в список. В этом случае работа выполняется только один раз.
Метод вызывается один раз, но массив повторяется дважды. Это не проблема в этом случае, но иногда это (например, если перечислены ленивые данные с веб-сайта) – Rob
Как увидеть, что массив был повторен дважды? – tesicg
вы дважды перебираете один и тот же массив. почему бы просто не заполнить свой 'StringBuilder' в первом цикле foreach? – user1666620