Рассмотрите этот бит запутываемого кода. Намерение состоит в том, чтобы создать новый объект на лету через анонимного конструктора и yield return
это. Цель состоит в том, чтобы избежать необходимости поддерживать локальный набор только только к return
это.
public static List<DesktopComputer> BuildComputerAssets()
{
List<string> idTags = GetComputerIdTags();
foreach (var pcTag in idTags)
{
yield return new DesktopComputer() {AssetTag= pcTag
, Description = "PC " + pcTag
, AcquireDate = DateTime.Now
};
}
}
К сожалению, этот бит кода производит исключение:
Ошибка 28 тело 'Нечто. BuildComputerAssets ()' не может быть блоком итератора потому что 'Система. Наборы. Универсальный. Список' не является типом интерфейса итератора
Вопросы
yield return
правильно? Вы можете использовать yield return
только в функции, которая возвращает IEnumerable
или IEnumerator
, но не List
.
Вам нужно изменить свою функцию, чтобы она возвращала IEnumerable
.
В качестве альтернативы вы можете переписать функцию для использования List
:
return GetComputerIdTags().ConvertAll(pcTag =>
new DesktopComputer() {
AssetTag = pcTag,
Description = "PC " + pcTag,
AcquireDate = DateTime.Now
});
Вы также можете реализовать ту же функциональность с помощью запроса LINQ (в C # 3.0+). Это менее эффективно, чем использование метода ConvertAll
, но является более общим. Позже вам также может потребоваться использовать другие функции LINQ, такие как фильтрация:
return (from pcTag in GetComputerIdTags()
select new DesktopComputer() {
AssetTag = pcTag,
Description = "PC " + pcTag,
AcquireDate = DateTime.Now
}).ToList();
Метод ToList
преобразует результат из IEnumerable
в List
. Мне лично не нравится ConvertAll
, потому что он выполняет то же самое, что и LINQ. Но поскольку он был добавлен ранее, его нельзя использовать с LINQ (он должен был называться Select
).
Ваша подпись метода неверна. Это должно быть:
public static IEnumerable<DesktopComputer> BuildComputerAssets()
yield работает только с типами итераторов:
Оператор yield может появиться только внутри блока итераторов
Итераторы определяются как
Возвращаемый тип итератора должен быть IEnumerable, IEnumerator, IEnumerable
или IEnumerator .
IList и IList