Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C#: Func<T, TResult> for generic methods

Tags:

c#

.net

generics

It is possible to create a Func object what references a generic method? like the LINQ OrderBy:

public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(
    this IEnumerable<TSource> source,
    Func<TSource, TKey> keySelector
)
like image 886
SDReyes Avatar asked May 14 '10 16:05

SDReyes


2 Answers

If I understand you correctly, you're asking if you can reference a generic method from within an anonymous method.

The answer is yes.

For example, suppose you want some Func that returns the elements of an IEnumerable<int> object in sorted order (precisely like OrderBy<int, int>). You could do this:

Func<IEnumerable<int>, Func<int, int>, IOrderedEnumerable<int>> orderByFunc =
    System.Linq.Enumerable.OrderBy<int, int>;

Then you could use this Func just like any other:

int[] ints = new int[] { 1, 3, 5, 4, 7, 2, 6, 9, 8 };

// here you're really calling OrderBy<int, int> --
// you've just stored its address in a variable of type Func<...>
foreach (int i in orderByFunc(ints, x => x))
    Console.WriteLine(i);

Output:

1
2
3
4
5
6
7
8
9

On the other hand, if you're asking whether it's possible to create a "generic anonymous method," like this:

Func<T> getDefault<T> = () => default(T);

Then it depends on your context. This can be done from within a context where T is already declared as a generic type parameter -- namely, within a generic class or generic method. (See Freddy Rios's answer.) Outside of such a context, unfortunately, it is illegal.

like image 71
Dan Tao Avatar answered Oct 15 '22 11:10

Dan Tao


Yes, but it depends on the context - if you are already working with generics, just use the T in the context / if not, then you already know the specific type. In the later, if you need to reuse a bit of logic on a method, u probably already would benefit of moving that into a method, so just do like my second example below.

2 samples:

public T Something<T>() {
    Func<T> someFunc = () => { return default(T); };
    return someFunc();
}

public Func<T> GetDefaultCreator<T>() {
    return () => { return default(T); };
}
like image 30
eglasius Avatar answered Oct 15 '22 11:10

eglasius