views:

2095

answers:

4

Hello, I used List<T>.First() as well as List<T>.Last() in my VS 2008 C# project, but when I've downgraded to 2005 I got errors like this:

'System.Collections.Generic.List' does not contain a definition for 'First'

As far as I understand, if still there are Find() and FindLast() methods there MUST be a very very simple way to get iterators to the first and last values, am I right? But I'm stuck with this and can't find anything useful :(

+11  A: 

First() and Last() are part of LINQ which is why they're not being found in your VS 2005 project.

If you're using a List<T> it's really, really easy to find the first and last values, assuming the list is non-empty:

T first = list[0];
T last = list[list.Count-1];

If you really need to use iterators you can implement the LINQ methods really easily:

public static T First<T>(IEnumerable<T> source)
{
    foreach (T element in source)
    {
        return element;
    }
    throw new InvalidOperationException("Empty list");
}

public static T Last<T>(IEnumerable<T> source)
{
    T last = default(T);
    bool gotAny = false;
    foreach (T element in source)
    {
        last = element;
        gotAny = true;
    }
    if (!gotAny)
    {
        throw new InvalidOperationException("Empty list");
    }
    return last;
}

(I suspect the real implementation of Last checks whether source is an IList<T> or not and returns list[list.Count-1] if so, to avoid having to iterate through the whole collection.)

As pointed out in the comments, these aren't extension methods - you'd write:

// Assuming the method is in a CollectionHelpers class.
Foo first = CollectionHelpers.First(list);

instead of

Foo first = list.First();

but the effect is the same.

Jon Skeet
I think that LINQ's First() and Last() are more complicated than just getting the first or the last item in the list. They accept a predicate that is used to search for the first or last item that satisfies the function. i.e - you can pass it a lambda function to find the first unique item.
Mel Green
The overloads which accept predicates are, yes. However, given that the OP is aware of Find and FindLast (which are the equivalent of those overloads) I assume he's actually interested in the parameterless ones.
Jon Skeet
Aren't extension methods part of .net 3.0, i.e. not in VS2005 (.net 2.0)
FryGuy
FryGuy: They're part of C# 3, yes - but you can still implement the same functionality with static methods and call them by passing in the argument. It'll be a case of calling First(list) instead of list.First, that's all.
Jon Skeet
+2  A: 

There are 2 problems here

  1. Both First and Last are extension methods. The compiler included in VS2005 do not support extension methods so there is no way to bind to them
  2. The First and Last methods are included in the 3.5 framework which is not usable from VS2005.
JaredPar
+1  A: 

First is not a method of List<T>. First is a static method on System.Linq.Enumerable in .net 3.5 .

David B
+1  A: 

Those are extension methods. You are bringing up a typical case against extension methods whereas they can be confusing since they seem to belong to the class, but are actually defined elsewhere entirely. For the first/last for a List, you can still use list[0] and list[list.Count-1] (with added error handling, of course).

Erich Mirabal