Dynamically set Func<> types

c#, func, types

Solution

Now that you showed what you really want, the answer is much more simple: As you are apparently only interested in the return value of that expression, you could change your code to this:

Type t = typeof(StavkaDokumenta).GetProperty(pd.Polje).PropertyType;
ParameterExpression pe = Expression.Parameter(typeof(StavkaDokumenta), "stavka");
Expression expr = Expressions.ResolveCompleteExpression(pe, pd.Expression);
Expression final = Expression.Convert(expr, t);

if (t == typeof(string))
{
    var lambda = Expression.Lambda<Func<string>>(final, null);
    o = lambda.Compile().Invoke();
}
else
{
    var lambda = Expression.Lambda(final, pe);
    o = lambda.Compile().DynamicInvoke(stavka);
}

Old answer:

You can use generics and implicit conversion to `Func<T>` to achieve this:

Func<T> GetFunc<T>(Func<T> func)
{
    return func;
}

Call it with a method group like so:

var foo = GetFunc(SomeMethod);

This assumes that `SomeMethod` looks like this:

decimal SomeMethod()
{
    // ...
}

`foo` will be of type `Func<decimal>`. If the return type of `SomeMethod` would be a `string`, the type of `foo` would be `Func<string>`.

What happens in this code is the following:

The parameter that is passed to `GetFunc` is a so-called "method group" and not a variable of type `Func<T>`. However, there exists an implicit conversion from a method group to a variable of `Func<T>`:

Func<decimal> func = SomeMethod; // an implicit conversion happens here

That implicit conversion is exactly what is happening here: Before `GetFunc` is even called, the method group `SomeMethod` is converted the a variable of type `Func<T>`. The concrete type used for `T` is additionally inferred by the compiler based on the return type of the method `SomeMethod()`. Our goal was to create an instance of `Func<T>` based on our method group. And because that already happens in the conversion of the parameter before the method is even called, we simply return that created instance from the method.

Problem

is there any way to set `Func<>` type arguments dynamically, so i don't have to use endless `if` statements? Something like: ``` Type t = Type.GetType("System.Decimal"); Func<t> foo = new Func<t>(some_function); ``` Instead of: ``` Func<Decimal> foo = new Func<Decimal>(some_function); ``` UPDATE: Here's a snippet from my code: ``` Type t = typeof(StavkaDokumenta).GetProperty(pd.Polje).PropertyType; ParameterExpression pe = Expression.Parameter(typeof(StavkaDokumenta), "stavka"); Expression expr = Expressions.ResolveCompleteExpression(pe, pd.Expression); Expression final = Expression.Convert(expr, t); if (t == typeof(decimal)) { var lambda = Expression.Lambda<Func<StavkaDokumenta, decimal>>(final, pe); o = lambda.Compile().Invoke(stavka); } if (t == typeof(decimal?)) { var lambda = Expression.Lambda<Func<StavkaDokumenta, decimal?>>(final, pe); o = lambda.Compile().Invoke(stavka); } else if (t == typeof(int)) { var lambda = Expression.Lambda<Func<StavkaDokumenta, int>>(final, pe); o = lambda.Compile().Invoke(stavka); } else if (t == typeof(int?)) { var lambda = Expression.Lambda<Func<StavkaDokumenta, int?>>(final, pe); o = lambda.Compile().Invoke(stavka); } else if (t == typeof(string)) { var lambda = Expression.Lambda<Func<string>>(final, null); o = lambda.Compile().Invoke(); } ``` pd.Polje is string - name of a property inside "StavkaDokumenta" class. pd.Expression is string expression that must evaluate to type of Polje. stavka is an instance of StavkaDokumenta.

Original source