Lambda expression that returns a delegate
Asked Answered
R

2

6

Hi I am trying to achive something like this;

Method<TObjectType>(m=>m.GetData); //m is the instance of TObjectType

if I can succeed on that, then I can visit this expression and get the GetData Method and use it for creating a dynamic sql query. I could do this by giving method name as a string however I don't want to break the strongly type world of my developer friends.

I know I have to give the exact definition of the delegate but this still doesn't helped me;

void Method<TObjectType>(Expression<Func<TObjectType, Delegate>> ex){/**/}

Do you have an idea?

Roncesvalles answered 31/7, 2012 at 7:18 Comment(5)
Do you know anything about GetData()? Do you know that it will always have zero parameters, or something like that?Stationer
If you do not know the signature of the GetData method you will be leaving the strongly typed world.Pox
This might help you as well #2840938Manilla
@Stationer signature of the method should be generic because this could be any method.Roncesvalles
@Erno I thought so I am afraidRoncesvalles
O
6

Unfortunately, there's barely such a thing as "a delegate". For most purposes (and especially: for resolving a MethodInfo), it must be a strongly-typed delegate. This is because GetData isn't a method, it is a method group. You really need to specify the method precisely, or have a known delegate-type (which ultimately does the same thing).

You have two practical options; work to object, or add a generic. For example:

void Method<TObjectType>(Expression<Func<TObjectType,object>> ex) {...}

would work, as would:

void Method<TObjectType, TValue>(Expression<Func<TObjectType,TValue>> ex) {...}

The caller would use:

Method<Foo>(x => x.GetData());

If you really want to use a delegate, the type must be predictable, for example:

void Method<TObjectType>(Expression<Func<TObjectType,Func<int>>> ex)

allowing:

Method<Foo>(x => x.GetData);

Alternatively, if you know (for example) that the method is always parameterless, but you don't know the return type; maybe something like:

void Method<TObjectType, TValue>(Expression<Func<TObjectType,Func<TValue>>> ex)

which allows:

Method<Foo, int>(x => x.GetData);
Oshea answered 31/7, 2012 at 7:30 Comment(4)
In this scenario I suppose you are assuming that the GetData method is parameterless so that you can define it using the Func<T>. Which means, I have to make lots of Method overrides, am I correct?Roncesvalles
@lazycoder I would advise against it, because you'll end up making a method with an insane number of generic type arguments, that is rather inconvenient to call. I would actually advise the simpler object/TValue approach, with the caller specifying x.GetData(). For more complex overloads, they can always specify x.GetData(123, "abc", DateTime.Now) - the expression tree will tell you what overload they used, and (if you want them) the parameter values.Oshea
@lazycode Worst case, you then need two overloads; one Func<TObjectType,object>, one Action<TObjectType> (for void methods)Oshea
thanks, I suppose I have two ways; one way is to force the developer to define at least one parameterless override and second is to as Erno said "leaving the strongly typed world." :)Roncesvalles
M
0

Are you looking for something like this?

object InvokeMethod(Delegate method, params object[] args){
    return method.DynamicInvoke(args);
}

int Add(int a, int b){
    return a + b;
}

void Test(){
    Console.WriteLine(InvokeMethod(new Func<int, int, int>(Add), 5, 4));
}
Manilla answered 31/7, 2012 at 7:29 Comment(1)
thank you for the answer but I don't want to invoke this method I just want developers to define something with strongly typedRoncesvalles

© 2022 - 2024 — McMap. All rights reserved.