C# – the appropriate way to strongly type the return of a generic function

cgenerics

I'm writing a filter function to return the specific type specified out of a larger collection of supertypes (objects for example). The idea is I give you an enumerable and you return me all the strings for example. you can write it this way without generics:

public static IEnumerable Filter(IEnumerable source, Type type)
{
    List<object> results = new List<object>();

    foreach(object o in source)
    {
        if(o != null && o.GetType() == type)
        {
            results.Add(o);
        }
    }

    return results;
}

if we want to return generics there are a few different ways to go about it.

As a straight port:

public static IEnumerable<TResult> Filter<TResult>
                          (IEnumerable source, Type type)

Pass in an 'example':

IEnumerable<TResult> Filter<TResult>
    (IEnumerable source, TResult resultType)

Ultimately what I think is cleanest:

public static IEnumerable<T> Filter<T>(IEnumerable source)

The second type would be called entirely with parameters (and infer the type):

Filter(myList, "exampleString");

where as the final version there would get called with a type specifier:

Filter<string>(myList);

What is the appropriate way to strongly type the return of a generic function, where the return type isn't automatically implied in the signature? (why?)

(Edit Note: Our input is NOT typed, e.g. IEnumerable<T>. At best it would be IEnumerable. This function is returning the Ts out of the whole collection of other types.)

Best Answer

The following extension method included in Linq does exactly what you need:

IEnumerable<T> OfType<T>(this IEnumerable enumerable);

Here is a usage example:

List<object> objects = //...

foreach(string str in objects.OfType<string>())
{
    //...
}

As you can see, they used the generic parameter as the return type specifier. This is simpler and safer than using a Type or a string and return a non type safe enumeration.