Листинг массива в IEnumerable <T>

Предположим, что у вас есть базовый класс Employee как таковой:

class Employee
{
   public string Name;
   public int Years;
   public string Department;
}

Затем (в отдельном классе) у меня есть следующие фрагменты кода (я думаю, что понимаю все, кроме последнего):

Я считаю, что следующий фрагмент кода работает, потому что инициализатор массива создает массив объектов Employee, которые являются тем же типом, что и переменная рабочей силы, которой назначено.

Employee[] workforceOne = new Employee[] {
   new Employee() { Name = "David", Years = 0, Department = "software" },
   new Employee() { Name = "Dexter", Years = 3, Department = "software" },
   new Employee() { Name = "Paul", Years = 4, Department = "software" } };

Затем я имею следующий фрагмент кода. Я считаю, что это работает, потому что массив Employee implicity - это реализация класса Array(), который реализует IEnumerable. Поэтому я считаю, что именно поэтому массив может быть назначен IEnumerable?

IEnumerable workforceTwo = new Employee[] {
   new Employee() { Name = "David", Years = 0, Department = "software" },
   new Employee() { Name = "Dexter", Years = 3, Department = "software" },
   new Employee() { Name = "Paul", Years = 4, Department = "software" } };

Тогда у меня есть этот фрагмент кода:

IEnumerable<Employee> workforceThree = new Employee[] {
   new Employee() { Name = "David", Years = 0, Department = "software" },
   new Employee() { Name = "Dexter", Years = 3, Department = "software" },
   new Employee() { Name = "Paul", Years = 4, Department = "software" } };

Я не уверен, почему этот фрагмент кода работает? IEnumerable<Employee> наследует от IEnumerable (и переопределяет (или перегружает?) метод GetEnumerator()), но поэтому мне не нужно заставлять за это работать как таковой:

//The cast does work but is not required
IEnumerable<Employee> workforceFour = (IEnumerable<Employee>)new Employee[] {
   new Employee() { Name = "David", Years = 0, Department = "software" },
   new Employee() { Name = "Dexter", Years = 3, Department = "software" },
   new Employee() { Name = "Paul", Years = 4, Department = "software" } };

Кажется, что массив неявно сбрасывается от типа IEnumerable до IEnumerable<Employee>, но я всегда думал, что когда вам нужно было преобразовать тип в нечто более конкретное, вам понадобилось явное приведение.

Может быть, я пропустил что-то простое в моем понимании здесь, но кто-то может помочь мне с моим пониманием вокруг этого.

Спасибо.

Ответ 1

Из документация:

В .NET Framework версии 2.0 класс Array реализует общие интерфейсы System.Collections.Generic.IList<T>, System.Collections.Generic.ICollection<T> и System.Collections.Generic.IEnumerable<T>. Реализации предоставляются массивам во время выполнения и поэтому не видны инструментам сборки документации. В результате общие интерфейсы не отображаются в синтаксисе объявления для класса Array, и нет никаких эталонных тем для членов интерфейса, которые доступны только путем литья массива в общий тип интерфейса (явные реализации интерфейса).

Таким образом, ваш Employee[] реализует IEnumerable<Employee>.

Ответ 2

Массив сотрудников по умолчанию реализует IEnumerable<Employee>, а также IEnumerable

Ответ 3

Явное приведение требуется, когда какое-то предложение должно быть подавлено. Это отличает объект к более специализированному типу - если объект имеет такой специализированный тип -.

С другой стороны, повышение уровня (кастинг для менее специализированного типа) никогда не потребует явного приведения, но вы можете явно сделать это (это просто бесполезно).

Так как Array реализует IEnumerable и IEnumerable<T>, вы делаете upcast в своем коде, то есть вам не нужно явно указывать на IEnumerable<T>.

Ответ 4

Я использовал для приведения объекта array в IEnumerable следующим образом

IEnumerable<Employee> enumerableEmp = workforceOne.Cast<Employee>();

где workforceone представляет собой массив сотрудников