tags:

views:

3404

answers:

5

I often want to grab the first element of an IEnumerable<T> in .net, and I haven't found a nice way to do it. The best I've come up with is:

foreach(Elem e in enumerable) {
  // do something with e
  break;
}

Yuck! So, is there a nice way to do this?

+21  A: 

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 do use:

var e = enumerable.FirstOrDefault(myDefault);

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 e = myDefault;
using (IEnumerator<Elem> enumer = enumerable.GetEnumerator()) {
    if (enumer.MoveNext()) e = enumer.Current;
}

Joel Coehoorn mentions .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().

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.

Erik Forbes
Thanks Joel - forgot about that one. Amended my post with details.
Erik Forbes
You should be `using` enumer - but other than that, good ;-p
Marc Gravell
Thanks Marc - edited. =)
Erik Forbes
+2  A: 

FirstOrDefault ?

Elem e = enumerable.FirstOrDefault();
//do something with e
David B
+2  A: 

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);
Adam Lassek
ElementAt(0), nice and simple.
JMD
+6  A: 

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...

BenAlabaster
You should be `using` iter
Marc Gravell
Oops, of course you're right, thanks. I've corrected my examples.
BenAlabaster
Iterators are disposable? Didn't know that...
Paul Betts
If you're on 2.0, you don't have var either.
recursive
Well I guess if you wanna get finicky I'll declare them properly :P
BenAlabaster
A: 

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).

Mouk
What evidence is there that the enumerator should be avoided? Performance tests on my machine indicate that it has an approximate 10% performance gain over foreach.
BenAlabaster
It depends on what you‘re enumerating over. An Erumerator could close connection to the Database, fush and close file handle, release some locked objects, etc. Not disposing an enumerator of some integer list won’t be harmfull, I guess.
Mouk