转换函数<类型,对象>表达式为Func其中T是一般约束
本文关键字:其中 约束 Func 表达式 类型 函数 对象 转换 | 更新日期: 2023-09-27 18:10:38
我有这个静态函数
public static object Create(Type t)
{
//unimportant
}
我不能控制上面的函数,所以我不能改变它。问题是它不是泛型的,所以我必须将返回的对象强制转换为某种类型。此类型由另一个泛型类的约束提供,我从其中调用Create
方法。
这是我到达的地方:
public static class Creator<T>
{
public static void Create()
{
var m = typeof(SomeClass).GetMethod("Create");
var p = Expression.Parameter(typeof(Type));
var e = Expression.Call(m, p);
//at this stage I want to create delegate for calling the 'Create' method,
//then pass typeof(T) as parameter, get returned object,
//and finally cast it to 'T'.
//for eg, I can do it like this:
var f = Expression.Lambda<Func<Type, object>>(e, p).Compile();
Func<T> mainThing = () => (T)f(typeof(T));
//is there a way I can achieve in one step?
}
}
在我上面的方法中,我没有编译最后的委托,而是提前一步。我如何在编译前也合并强制转换并获得Func<T>
?
你似乎跳过了很多不必要的环节。我不明白你为什么要用表达式树来做这个。为什么不直接:
public static class Creator<T>
{
public static void Create()
{
Func<T> mainThing = () => (T)SomeClass.Create(typeof(T));
}
}
? ?
创建一个方法调用的表达式树的目的是什么,只是把它变成一个委托,使一个方法调用,然后调用?为什么不直接打电话给SomeClass.Create
?
我在这里错过了什么吗?
回答你的实际问题:
如何在编译前合并强制转换?
使用Expression.Convert()
创建表示转换的表达式树节点
我认为你只需要调用Expression.Convert
,并使用ConstantExpression
而不是ParameterExpression
:
var method = typeof(SomeClass).GetMethod("Create");
var call = Expression.Call(method, Expression.Constant(typeof(T), typeof(Type)));
var conversion = Expression.Convert(call, typeof(T));
var function = Expression.Lambda<Func<T>>(conversion).Compile();
(我还没有测试,但它看起来不错…)