tags:

views:

245

answers:

6

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
)
A: 

Something like this?

Func<Nullable<int>, string> myFunc = c => c.HasValue ? c.ToString() : "null";

That successfully compiles, and you could assign any function to that that takes in a Nullable and returns a string.

CubanX
Hi CubanX!, not really. you're referencing a lambda which takes a nullable object and return a string. I'm trying to reference a generic method (which receives a type TSource for example) Thanks a lot!
SDReyes
A: 

Yes it's possible but you'll need to specify the type argument(s)

func f = myClass.returnsT;

where class myClass { T returnsT() {...} }

it Will not work without the type arguments

Rune FS
A: 

I have done something like this:

public static class Helper{

public static IEnumerable<KeyValuePair<string, string>> ToPairs(this NameValueCollection Form)
        {
            return Form.AllKeys.Cast<string>()
                .Select(key => new KeyValuePair<string, string>(key, Form[key]));
        }
}

Where this method has become an extension method to the request.form in C# web development.

Arnej65
Hi Arne, thanks for your answer. nonetheless this is not a generic method. thank you again
SDReyes
+2  A: 

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.

Dan Tao
Thank you Dan! nice answer +1. you mean it is not possible to define a generic `Func` object? : O
SDReyes
@SDReyes: That depends on whether or not you have a `T` that is defined within your scope. That is, if you're working within a generic class, for example, then within a method in that class you might be able to declare a `Func<T>`. You could also do this within a generic method. But to declare a generic anonymous method in a context that isn't already generic (i.e., from within any plain vanilla non-generic method belonging to some non-generic class) is, I'm afraid, not possible.
Dan Tao
@Dan Tao: Thanks a lot Dan : )
SDReyes
+1  A: 

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); };
}
eglasius
Thank you Freddy so clear +1
SDReyes
A: 

I think I get it: Given the function static TResult DoSomeStuff<T, TResult>(T obj), can you create a Func<T, TResult> such that it will reference the function above, with no type parameters given at the creation of the reference to it.
I think this could work (You're welcome to test it, I have no C# near me at the moment):

class UselessClass<T, TResult>
{
   // If it's a static method, this is fine:
    public Func<T, TResult> DaFunc = RelevantClass.DoSomeStuff<T, TResult>;
    // If not, something like this is needed:
    public UselessClass(SomeClassWhereTheFunctionIs from)
    {
       DaFunc = from.DoSomeStuff<T, TResult>;
    }
}

Also, in OrderBy, it's not actually a generic delegate. It's a declaration of a variable. When the function is given to it, the types are inferred from it.

Rubys