79 votes

Conversion d'un tableau en IEnumerable<T>

Supposons que vous ayez une base Employee comme tel :

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'initialisateur de tableau crée un tableau d'objets employés qui sont du même type que la variable workforce à laquelle il est affecté.

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 alors le fragment de code suivant. Je pense que cela fonctionne parce que le tableau de Employee L'implicite des objets 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 assigné à 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 surcharge (ou surcharge ?) la fonction GetEnumerator() ) mais ne devrais-je pas avoir besoin d'un casting pour que la méthode ci-dessus fonctionne comme telle ?

//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 coulé vers le bas à partir d'un type de IEnumerable a IEnumerable<Employee> mais j'ai toujours pensé que lorsqu'on avait besoin de convertir un type en quelque chose de plus spécifique, il fallait un cast explicite.

Peut-être que je manque quelque chose de simple dans ma compréhension, mais quelqu'un peut-il m'aider à comprendre ce qui se passe ?

Gracias.

3 votes

@Aliostad : C'est juste en dessous du workforceThree fragment.

116voto

Heinzi Points 66519

De la documentation :

Dans la version 2.0 de .NET Framework, la classe Array implémente la fonction System.Collections.Generic.IList<T> , System.Collections.Generic.ICollection<T> y System.Collections.Generic.IEnumerable<T> interfaces génériques. Les implémentations sont fournies aux tableaux 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'y a pas de sujets de référence pour les membres de l'interface qui ne sont accessibles qu'en coulant un tableau vers le type d'interface générique (implémentations explicites de l'interface).

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

12 votes

Pour clarifier, ce n'est pas la classe Array qui l'implémente, c'est T[] de n'importe quel T.

5voto

Dennis Traub Points 24186

Par défaut, le tableau des employés implémente IEnumerable<Employee> ainsi que IEnumerable

3voto

Matías Fidemraizer Points 16842

Un moulage explicite est nécessaire lorsqu'une phrase doit être downcasted . C'est le casting d'un objet vers un type plus spécialisé - si l'objet est d'un tel type spécialisé -.

D'un autre côté, upcasting (casting vers un type moins spécialisé), n'aura jamais besoin d'un cast explicite, mais vous pouvez le faire explicitement (c'est juste inutile).

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

3 votes

Je ne suis pas d'accord. Dans certains cas, vous avez besoin d'un upcast explicite. Par exemple, la fonction override : void DoStuffs(IEnumerable<T> objects) { ... } void DoStuffs(params T[] objects) { DoStuffs((IEnumerable<T>) objects) ; }

2 votes

@Orace Ce n'est pas exactement un upcast... C'est une aide du compilateur pour lui permettre d'invoquer la surcharge désirée... vous êtes d'accord ? ;) C'est un problème de résolution de surcharge de méthode.

0 votes

@Orace Eh bien, c'est un upcast, mais je veux dire que vous avez besoin du "cast" explicite pour invoquer la surcharge souhaitée ...

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X