tags:

views:

65

answers:

3

As an exercise I'm trying to create a function that returns a generic list from another generic list that's passed to the function. The list passed in could be of either int or string, and I want to return a list of all members of the passed in list that have an even number of characters. The way I'm doing it isn't correct and it doesn't compile, but I want to know why. (I'm using an anonymous method which I know can be replaced with a Lambda expression, but I'd like to know first why it's not working).

List<T> GetEvens(List<T> list)
{
    List<T> newList = 
        list.FindAll(delegate(T t)
        {return t.ToString().Length() % 2 == 0;});

    return newList;
}

I'm getting an error on lines 3 and 4 saying "The type or namespace name 'T' could not be found". Why doesn't the function recognise 'T'? I know the function will work if I make it a specific return type such as string, but then I'd have to create a separate function for every type I wanted to use which doesn't seem very efficient.

A: 

The reason is that there's no Length method. It's a property so you don't need the parentheses:

return t.ToString().Length % 2 == 0;

But to make you code shorter:

public List<T> GetEvens(List<T> list)
{
    return list.FindAll(t => t.ToString().Length % 2 == 0);
}
Darin Dimitrov
I didn't type fast enough :)
slugster
Thanks Darin well spotted but this isn't the main problem. The function doesn't recognise the generic 'T' type when I try to use it to create 'newList' or when passed to the delegate.
Ciaran Bruen
Well then you need to specify it either at the class containing this method or at the method itself: `List<T> GetEvens<T>(List<T> list)`
Darin Dimitrov
Ok same question as below - what does GetEvens<T>(...) do as opposed to just GetEvens(...)?
Ciaran Bruen
It declares the `T` generic parameter you are using inside this function. Every time you need to use a generic parameter this parameter needs to be declared somewhere (usually this is done at the class containing the method or at the method itself as my example).
Darin Dimitrov
Ok that works cheers - would have thought by returning List<T> that would have declared the T parameter.
Ciaran Bruen
A: 

Length is a property, not a method, so remove the brackets from it.

slugster
+4  A: 

Try List<T> GetEvens<T>( ... )

corvuscorax
Ok will try - what does GetEvens<T>(...) do as opposed to just GetEvens(...)? Isn't having the function as type List<T> sufficient?
Ciaran Bruen
It's a syntactic thing - basically it just tells the compiler that you're defining a generic method. The type parameters between the angle brackets define what types the method is parameterized on.
corvuscorax
Nice one cheers. Hmmm doesn't SO allow more than one answer? Both you guys got it but I think Darin was in there first :)
Ciaran Bruen
@Ciaran Bruen: corvuscorax actually answered your question (why does the compiler complain about the unknown symbol "T"?), while Darin Dimitrov on the other hand pointed you at another bug in your code.
Novox
Ok corrected thanks @Novox
Ciaran Bruen