8

有没有办法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 的一个实例。

4

1 回答 1

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>。如果返回类型为SomeMethoda string,则类型fooFunc<string>


此代码中发生的情况如下:

传递给的参数是GetFunc所谓的“方法组”,而不是类型的变量Func<T>。但是,存在从方法组到变量的隐式转换Func<T>

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

这种隐式转换正是这里发生的事情:在GetFunc调用之前,方法组SomeMethod被转换为 a 类型的变量Func<T>。用于的具体类型T由编译器根据方法的返回类型额外推断SomeMethod()
我们的目标是Func<T>基于我们的方法组创建一个实例。并且因为在调用方法之前参数的转换已经发生了这种情况,所以我们只需从方法中返回创建的实例。

于 2012-04-16T14:47:13.947 回答