Відлиття масиву до IEnumerable <T>


76

Припустимо, у вас є базовий 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об’єктів об’єктів є реалізацією класу 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>але я завжди думав, коли вам потрібно перетворити тип на щось більш конкретне, вам потрібен явний привід.

Можливо, мені не вистачає тут чогось простого в моєму розумінні, але чи може хтось допомогти мені з моїм розумінням навколо цього.

Дякую.


3
@Aliostad: Це прямо під workforceThreeфрагментом.
Heinzi

Відповіді:


114

З документації :

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

Таким чином, ваші Employee[]знаряддя IEnumerable<Employee>.


12
Щоб уточнити, це реалізує не клас Array, це T [] будь-якого Т.
IllidanS4 підтримує Моніку


3

Явний акторський склад необхідний, коли деяке речення потрібно зменшити . Це перекидання об’єкта на більш спеціалізований тип - якщо об’єкт такого спеціалізованого типу -.

З іншого боку, оновлення (трансляція до менш спеціалізованого типу) ніколи не потребуватиме явного приведення, але ви можете явно це зробити (це просто марно).

Оскільки Array реалізує IEnumerableі IEnumerable<T>, ви робите оновлення у своєму коді, тобто _ вам не потрібно явно призначати IEnumerable<T>.


3
Я не згоден. У деяких випадках вам потрібне явне оновлення. Як приклад перевизначення функції: void DoStuffs (IEnumerable <T> objects) {...} void DoStuffs (params T [] objects) {DoStuffs ((IEnumerable <T>) objects); }
Орація,

2
@Orace Це не зовсім оновлення ... Це допомога компілятора, щоб дозволити йому викликати бажане перевантаження ... Ви згодні? ;) Це проблема вирішення перевантаження методу.
Matías Fidemraizer

@Orace Ну, це оновлення, але я маю на увазі, що вам потрібен явний "
привід
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.