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