C# приведение элементов к типу интерфейса IEnumerable

292
07 января 2018, 03:58

В методичке идёт пояснение по поводу стандартных интерфейсов и ключевого слова 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" может быть любой элемент?
  2. Зачем из метода Count() возвращать цифры типа "IEnumerable", если можно их возвращать в их изначальном типе "int"? Да, это, насколько я знаю, нужно чтобы метод мог использоваться в цикле foreach, но почему foreach не переваривает типы отличные от "IEnumerable"?
Answer 1

1) Нет. Типом IEnumerable может быть только тип, реализующий IEnumerable

2) Вы неверно поняли, что происходит. Вы видите по сути один код, но выполняется другой. При использовании ключевого слова yield, компилятор сгенерирует новый класс, реализующий IEnumerable, энумератор которого будет использовать вашу функцию для получения следующего элемента при перечислении. Подробнее тут - в секции Returning IEnumerable.

Answer 2

Смотрите, что тут происходит.

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.)

READ ALSO
Считывание комбинации клавиш программой свёрнутой в трей

Считывание комбинации клавиш программой свёрнутой в трей

Здравствуйте! Мне бы хотелось, чтобы моя [недо]программа, которая уже свёрнута в трей выполняла определённые события при нажатии определённых...

254
Не работает Trigger2D

Не работает Trigger2D

Создал объект с sprite renderer, collider2D,Rigidbody2DСоздал Sphere collider с IsTrigger

222
сколько времени уйдет на изучения языка программирования? [требует правки]

сколько времени уйдет на изучения языка программирования? [требует правки]

Cколько времени уйдет на изучения языка программирования? овладеть если так можно выразиться

186
ASP.Net WebAPI + winforms

ASP.Net WebAPI + winforms

Всем доброго времени сутокЕсть задание, создать набор приложений для парсинг лог файла

297