Листинг массива в 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
представляет собой массив сотрудников