A lambda expression cannot introduce generic parameters, there is no syntax for it. You will have to use generic methods instead of lambdas, and use reflection to construct closed generic methods for particular types, like this (code not tested):
public Func<T, int> GetLambdaFor<T> ()
{
return GetLambdaFor<T> (m_method, m_target) ;
}
public void SetLambdaForAnyType (Func<object, int> lambda)
{
if (lambda == null) throw new ArgumentNullException ("lambda") ;
// delegate complicated signature checks to CLR
try
{
var definition = lambda.Method.GetGenericMethodDefinition () ;
GetLambdaFor<Dummy> (definition, lambda.Target) ;
m_method = definition ;
m_target = lambda.Target ;
}
catch (Exception e)
{
throw new ArgumentException ("lambda", e) ;
}
}
private sealed class Dummy {}
private MethodInfo m_method ;
private object m_target ;
static Func<T, int> GetLambdaFor<T> (MethodInfo method, object target)
{
return (Func<T, int>) Delegate.CreateDelegate (typeof (Func<T, int>),
target, method.MakeGenericMethod (typeof (T))) ;
}
Then you use it like this
// in your class
private static int GetValueFromGenerator<T> (T a)
{
return new SomeValueGenerator<T> (a).GetValue () ;
}
MyClass.SetLambdaForAnyType (GetValueFromGenerator) ;
Finally, if your 'lambdas' will always be of this form, you might want to introduce an interface for GetValue
and instead of creating generic methods on-the-fly, create generic types for these generators, activate them and cast to IGetValue
.