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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With