8 thoughts on “How do I get the first element from an IEnumerable in .net?

  1. user

    Use FirstOrDefault or a foreach loop as already mentioned. Manually fetching an enumerator and calling Current should be avoided. foreach will dispose your enumerator for you if it implements IDisposable. When calling MoveNext and Current you have to dispose it manually (if aplicable).

    Reply
  2. user

    If your IEnumerable doesn’t expose it’s <T> and Linq fails, you can write a method using reflection:

    public static T GetEnumeratedItem<T>(Object items, int index) where T : class
    {
      T item = null;
      if (items != null)
      {
        System.Reflection.MethodInfo mi = items.GetType()
          .GetMethod("GetEnumerator");
        if (mi != null)
        {
          object o = mi.Invoke(items, null);
          if (o != null)
          {
            System.Reflection.MethodInfo mn = o.GetType()
              .GetMethod("MoveNext");
            if (mn != null)
            {
              object next = mn.Invoke(o, null);
              while (next != null && next.ToString() == "True")
              {
                if (index < 1)
                {
                  System.Reflection.PropertyInfo pi = o
                    .GetType().GetProperty("Current");
                  if (pi != null) item = pi
                    .GetValue(o, null) as T;
                  break;
                }
                index--;
              }
            }
          }
        }
      }
      return item;
    }
    
    Reply
  3. user

    If you can use LINQ you can use:

    var e = enumerable.First();
    

    This will throw an exception though if enumerable is empty: in which case you can use:

    var e = enumerable.FirstOrDefault();
    

    FirstOrDefault() will return default(T) if the enumerable is empty, which will be null for reference types or the default ‘zero-value’ for value types.

    If you can’t use LINQ, then your approach is technically correct and no different than creating an enumerator using the GetEnumerator and MoveNext methods to retrieve the first result (this example assumes enumerable is an IEnumerable<Elem>):

    Elem e = myDefault;
    using (IEnumerator<Elem> enumer = enumerable.GetEnumerator()) {
        if (enumer.MoveNext()) e = enumer.Current;
    }
    

    Joel Coehoorn mentioned .Single() in the comments; this will also work, if you are expecting your enumerable to contain exactly one element – however it will throw an exception if it is either empty or larger than one element. There is a corresponding SingleOrDefault() method that covers this scenario in a similar fashion to FirstOrDefault(). However, David B explains that SingleOrDefault() may still throw an exception in the case where the enumerable contains more than one item.

    Edit: Thanks Marc Gravell for pointing out that I need to dispose of my IEnumerator object after using it – I’ve edited the non-LINQ example to display the using keyword to implement this pattern.

    Reply
  4. user

    Well, you didn’t specify which version of .Net you’re using.

    Assuming you have 3.5, another way is the ElementAt method:

    var e = enumerable.ElementAt(0);
    
    Reply
  5. user

    Just in case you’re using .NET 2.0 and don’t have access to LINQ:

     static T First<T>(IEnumerable<T> items)
     {
         using(IEnumerator<T> iter = items.GetEnumerator())
         {
             iter.MoveNext();
             return iter.Current;
         }
     }
    

    This should do what you’re looking for…it uses generics so you to get the first item on any type IEnumerable.

    Call it like so:

    List<string> items = new List<string>() { "A", "B", "C", "D", "E" };
    string firstItem = First<string>(items);
    

    Or

    int[] items = new int[] { 1, 2, 3, 4, 5 };
    int firstItem = First<int>(items);
    

    You could modify it readily enough to mimic .NET 3.5’s IEnumerable.ElementAt() extension method:

    static T ElementAt<T>(IEnumerable<T> items, int index)
    {
        using(IEnumerator<T> iter = items.GetEnumerator())
        {
            for (int i = 0; i <= index; i++, iter.MoveNext()) ;
            return iter.Current;
        }
    } 
    

    Calling it like so:

    int[] items = { 1, 2, 3, 4, 5 };
    int elemIdx = 3;
    int item = ElementAt<int>(items, elemIdx);
    

    Of course if you do have access to LINQ, then there are plenty of good answers posted already…

    Reply

Leave a Reply

Your email address will not be published.