web-dev-qa-db-fra.com

Casting array to IEnumerable <T>

Supposons que vous avez une classe Employee de base en tant que telle:

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

Ensuite (dans une classe séparée) j'ai les fragments de code suivants (je pense que je comprends tout sauf le dernier):

Je pense que le fragment de code suivant fonctionne parce que l'initiateur de tableau crée un tableau d'objets Employé du même type que la variable d'effectif à affecter.

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" } };

J'ai ensuite le fragment de code suivant. Je pense que cela fonctionne car le tableau de implicitance des objets Employee est une implémentation de la classe Array () qui implémente IEnumerable. Par conséquent, je crois que c’est la raison pour laquelle le tableau peut être affecté à 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" } };

Ensuite, j'ai ce fragment de code:

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" } };

Je ne suis pas sûr de savoir pourquoi ce fragment de code fonctionne?IEnumerable<Employee> Hérite de IEnumerable (et substitue (ou surcharge?) La méthode GetEnumerator()) mais Je n’aurais donc pas besoin d’un casting pour que ce qui précède fonctionne comme tel:

//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" } };

Il semble que le tableau soit implicitement réduit d'un type de IEnumerable à IEnumerable<Employee>, Mais j'ai toujours pensé que lorsque vous deviez convertir un type en quelque chose de plus spécifique, vous deviez recourir à une conversion explicite.

Peut-être me manque-t-il quelque chose de simple dans ma compréhension ici, mais quelqu'un peut-il m'aider s'il vous plaît à m'aider à comprendre.

Merci.

71
Dangerous

De la documentation :

Dans le .NET Framework version 2.0, la classe Array implémente le System.Collections.Generic.IList<T>, System.Collections.Generic.ICollection<T>, et System.Collections.Generic.IEnumerable<T> interfaces génériques. Les implémentations sont fournies aux baies au moment de l'exécution et ne sont donc pas visibles pour les outils de construction de la documentation. Par conséquent, les interfaces génériques n'apparaissent pas dans la syntaxe de déclaration de la classe Array et il n'existe aucune rubrique de référence pour les membres d'interface accessible uniquement en convertissant un tableau en type d'interface générique (implémentations d'interface explicite).

Ainsi, votre Employee[] met en oeuvre IEnumerable<Employee>.

101
Heinzi

Le tableau d'employés implémente par défaut IEnumerable<Employee> ainsi que IEnumerable

4
Dennis Traub

Une conversion explicite est nécessaire lorsque certaines phrases doivent être downcasted . Cela transforme un objet en un type plus spécialisé - si l'objet est d'un tel type spécialisé -.

D'autre part, la conversion ascendante (conversion vers un type moins spécialisé), n'aura jamais besoin d'une diffusion explicite, mais vous pouvez le faire explicitement (c'est simplement inutile ).

Puisque Array implémente IEnumerable et IEnumerable<T>, vous faites un pcast dans votre code, ce qui signifie que vous n'avez pas besoin de transtyper explicitement en IEnumerable<T>.

3
Matías Fidemraizer