В методичке идёт пояснение по поводу стандартных интерфейсов и ключевого слова yield:
Следующий пример демонстрирует перебор значений в заданном диапазоне (от 1 до N) (пример 3.3). Листинг 3.3 Статический метод реализующий интерфейс IEnumerable
using System;
using System.Collections;
namespace StdIFace
{
class ExampleIEnumerableClass
{
public static IEnumerable Count(int to)
{
int from = 1;
while (from <= to)
yield return from++;
}
static void Main()
{
foreach (int i in Count(5))
Console.WriteLine(i);
Console.Read();
}
}
}
Из метода Count() возвращаются цифры от 1 до 5 включительно, при этом в самом методе эти цифры типа "int", а из метода эти цифры возвращаются уже с типом "IEnumerable". Далее в цикле foreach эти цифры присваиваются переменной "i" и при присвоении, получается, они явно преобразовываются из "IEnumerable" в "int" и потом уже выводятся в консольку(это так, как я понял).
Если я не правильно рассуждаю, поправьте, пожалуйста.
Собственно вопрос:
1) Нет. Типом IEnumerable может быть только тип, реализующий IEnumerable
2) Вы неверно поняли, что происходит. Вы видите по сути один код, но выполняется другой. При использовании ключевого слова yield, компилятор сгенерирует новый класс, реализующий IEnumerable, энумератор которого будет использовать вашу функцию для получения следующего элемента при перечислении. Подробнее тут - в секции Returning IEnumerable.
Смотрите, что тут происходит.
IEnumerable — это последовательность элементов. То есть, она представляет собой не один элемент, а несколько. Поэтому поменять возвращаемый тип метода Count на int не получится: с int вы можете вернуть лишь одно значение, а с IEnumerable — много.
Как ни странно, ваша методичка упоминает давно устаревший нетипизированный IEnumerable, в котором и правда в последовательности могут быть элементы любого типа. Более современный и эффективный вариант — IEnumerable<int>, который позволяет возвращать последовательность только int-значений.
foreach нужен для итерации по последовательностям, поэтому он не принимает одиночные элементы. Если бы функция возвращала просто int, вам не был бы нужен цикл.
Функция с yield return — это нестандартный, но очень популярный способ создавать последовательности. При этом оператор yield return не возвращает результат функции, а всего лишь одно, следующее значение элемента коллекции. В течение выполнения функции yield return может выполняться несколько раз (в отличие от return, который всегда выполняется лишь один раз), и каждый раз это даёт новое значение в последовательности.
Когда в цикле foreach происходит итерация по нетипизированному IEnumerable, и в коде задаётся тип переменной итерации (в вашем случае int i), происходит приведение типа элемента последовательности к типу int. (Если в вашей коллекции вдруг окажется не int, произойдёт ошибка приведения типов: https://ideone.com/epx61b.)
Сборка персонального компьютера от Artline: умный выбор для современных пользователей