2009-07-14 8 views
1

Dans l'exemple ci-dessous, si le code client utilisant GetPeople voulait imprimer le nom et l'âge de chaque personne sur la console, il devrait utiliser reflet (je suppose) pour déterminer que cette requête contenait un IEnumerable (Of Person). en tant que tel pour obtenir à ses propriétés.Quand, le cas échéant, IEnumerable doit-il être utilisé sur IEnumerable <T>?

Public Function GetPeople() As IEnumerable 
    Dim query = From p As Person In People.AsEnumerable() _ 
       Select p 
    Return query 
End Function 

La forme générique de IEnumerable semble beaucoup plus instructif et utile aux clients:

Public Function GetPeople() As IEnumerable(Of Person) 
    Dim query = From p As Person In People.AsEnumerable() _ 
       Select p 
    Return query 
End Function 

Je suis sûr qu'il ya une raison - alors, pourquoi IEnumerable jamais favorisée par rapport à IEnumerable (Of T) ?

Merci.

Répondre

8

Jamais, pour autant que je puisse voir. IEnumerable<T> hérite IEnumerable, exposant ainsi IEnumerable<T> communique ce que vous savez sur T à l'appelant, tout en permettant toujours aux fonctions écrites avant les génériques d'utiliser la collection.

La raison non-IEnumerable existe est historique.

+0

Généralement, j'implémente IEnumerable.GetEnumerator() en tant qu'implémentation d'interface explicite, et j'ai IEnumerable .GetEnumerator() en tant qu'implémentation implicite. De cette façon, il est toujours compatbile en arrière (pour le code non générique) mais en utilisant la classe normalement est entièrement générique – thecoop

2

La seule fois que j'ai trouvé où j'utiliserais IEnumerable sur IEnumerable<T> est lorsqu'il s'agit de requêtes LINQ et d'objets anonymes. Considérez ce qui suit (pièce) par exemple:

class Person 
{ 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
} 

IEnumerable<object> GetFirstNames(IEnumerable<Person> people) 
{ 
    return from p in people 
      select new 
      { 
       Name = p.FirstName 
      }; 
} 

Cela va générer l'erreur suivante:

error CS0266: Cannot implicitly convert type 'System.Collections.Generic.IEnumerable<AnonymousType#1>' to 'System.Collections.Generic.IEnumerable<object>'. An explicit conversion exists (are you missing a cast?)

Cependant, si vous changez le type de retour de GetFirstNames()-IEnumerable, il compilera.

+1

Je préférerais personnellement laisser la signature comme IEnumerable , et changer le code pour sélectionner nouveau {Name = p.FirstName} .Dernier (); – mquander

0

Si vous n'avez pas de génériques disponibles, c'est-à-dire que vous utilisez .NET 1.1.

0

Peut-être pas comme valeur de retour. Sinon, utilisez-le dans la mesure du possible - si vous pouvez vous en sortir. Cela rendra votre code plus général puisque IEnumerable est un IEnumerable plus général <>.

Par exemple, considérons une fonction générale qui imprime simplement les valeurs null-nun d'un IEnumerable.

Questions connexes