动态设置Func <>类型

Mil*_*vic 8 c# types func

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

Dan*_*rth 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);
}
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,类型fooFunc<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>基于我们的方法组创建一个实例.并且因为在调用方法之前已经在参数转换中发生了这种情况,我们只是从方法中返回该创建的实例.

  • 'Expressions.ResolveCompleteExpression'方法在哪里?我没有看到它. (2认同)