有没有办法Func<>
动态设置类型参数,所以我不必使用无穷无尽的if
语句?
就像是:
Type t = Type.GetType("System.Decimal");
Func<t> foo = new Func<t>(some_function);
Run Code Online (Sandbox Code Playgroud)
代替:
Func<Decimal> foo = new Func<Decimal>(some_function);
Run Code Online (Sandbox Code Playgroud)
更新:
这是我代码中的代码段:
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();
}
Run Code Online (Sandbox Code Playgroud)
pd.Polje是字符串 - "StavkaDokumenta"类中属性的名称.pd.Expression是字符串表达式,必须根据Polje的类型进行评估.stavka是StavkaDokumenta的一个实例.
既然你展示了你真正想要的东西,答案就更简单了:因为你显然只对该表达式的返回值感兴趣,你可以将代码更改为:
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);
}
Run Code Online (Sandbox Code Playgroud)
老答案:
您可以使用泛型和隐式转换Func<T>
来实现此目的:
Func<T> GetFunc<T>(Func<T> func)
{
return func;
}
Run Code Online (Sandbox Code Playgroud)
使用方法组调用它,如下所示:
var foo = GetFunc(SomeMethod);
Run Code Online (Sandbox Code Playgroud)
这假设SomeMethod
看起来像这样:
decimal SomeMethod()
{
// ...
}
Run Code Online (Sandbox Code Playgroud)
foo
将是类型Func<decimal>
.如果返回类型SomeMethod
将是string
,类型foo
是Func<string>
.
此代码中发生的情况如下:
传递给的参数是GetFunc
所谓的"方法组",而不是类型的变量Func<T>
.但是,存在从方法组到变量的隐式转换Func<T>
:
Func<decimal> func = SomeMethod; // an implicit conversion happens here
Run Code Online (Sandbox Code Playgroud)
隐式转换正是这里发生的事情:GetFunc
甚至在调用之前,方法组SomeMethod
被转换为类型的变量Func<T>
.用于的具体类型T
由编译器根据方法的返回类型另外推断SomeMethod()
.
我们的目标是Func<T>
基于我们的方法组创建一个实例.并且因为在调用方法之前已经在参数转换中发生了这种情况,我们只是从方法中返回该创建的实例.