2009-06-05 8 views
6

J'ai une liste d'objets IEnumerable en C#. Je peux utiliser un pour chaque pour faire une boucle et examiner chaque objet bien, mais dans ce cas, tout ce que je veux faire est d'examiner le premier objet est-il un moyen de le faire sans utiliser une boucle foreach?C# IEnumerable Récupérer le premier enregistrement

J'ai essayé mylist [0] mais cela n'a pas fonctionné.

Merci

Répondre

22

(Par souci de commodité, cette réponse suppose myList met en œuvre IEnumerable<string>;. Remplacer string avec le type approprié si nécessaire)

Si vous utilisez .NET 3.5, utilisez l'extension First() méthode:

string first = myList.First(); 

Si vous n'êtes pas sûr si des valeurs ou non, vous pouvez utiliser la méthode FirstOrDefault() qui retournera null (ou plus généralement, la valeur par défaut du type d'élément) pour une séquence vide.

Vous pouvez le faire encore « le long chemin » sans boucle foreach:

using (IEnumerator<string> iterator = myList.GetEnumerator()) 
{ 
    if (!iterator.MoveNext()) 
    { 
     throw new WhateverException("Empty list!"); 
    } 
    string first = iterator.Current; 
} 

Il est assez laid bien :)

En réponse à votre commentaire, non, le itérateur retourné est pas positionné au premier élément initialement; il est positionné avant le premier élément. Vous devez appeler le MoveNext() pour le déplacer vers le premier élément, et c'est ainsi que vous pouvez faire la différence entre une séquence vide et une autre avec un seul élément.

EDIT: En y réfléchissant, je me demande si c'est un méthode d'extension utile:

public static bool TryFirst(this IEnumerable<T> source, out T value) 
{ 
    using (IEnumerator<T> iterator = source.GetEnumerator()) 
    { 
     if (!iterator.MoveNext()) 
     { 
      value = default(T); 
      return false; 
     } 
     value = iterator.Current; 
     return true; 
    } 
} 
+0

Est-mylist.GetEnumerator() courant égal à cela.? J'aimerais savoir juste pour le savoir. –

+0

Je ne suis pas sûr si j'aime la méthode d'extension car son paramètre out le rend moins composable. Je sais que c'est le point de la méthode dans ce cas mais avoir quelque chose de non-composable sur une séquence semble faux. –

+0

Le résultat de ceci n'est cependant pas une séquence - il ne s'agira jamais que d'un seul élément et d'un booléen, il devrait donc être à la fin de la chaîne de composition. Je pense que si vous regardiez des endroits où vous voudriez réellement cela, ce ne serait pas un problème. Comme vous le dites, c'est le but de la méthode. –

3

Rappelez-vous, il peut ne pas y avoir de "premier élément" si la séquence est vide.

 IEnumerable<int> z = new List<int>(); 
     int y = z.FirstOrDefault(); 
+0

Pour utiliser FirstOrDefault(), vous devez déclarer "using System.Linq;" – Tony

2

Si vous n'êtes pas sur 3,5:

using (IEnumerator<Type> ie = ((IEnumerable<Type>)myList).GetEnumerator()) { 
    if (ie.MoveNext()) 
     value = ie.Current; 
    else 
     // doesn't exist... 
} 

ou

Type value = null; 
foreach(Type t in myList) { 
    value = t; 
    break; 
} 
Questions connexes