Lambda表达式:将参数转换为基本类型

时间:2011-05-03 06:58:07

标签: c# lambda generics

我想“包装”特定属性的getter函数,该属性是特定类型的一部分。 我有一个抽象类,定义如下:

public abstract class MyAbstractClass<T> where T : MyType
{
    // ...
}

好吧,假设我有一个类似下面的具体类:

public abstract class MyConcreteClass : MyAbstractClass<MyConcreteType>
{
    // ...
}

现在,应该返回getter方法的包装器的辅助方法:

private Func<MyAbstractClass<T>, Object> GetPropertyGetter(PropertyInfo property)
{
    var instanceType = Expression.Parameter(property.DeclaringType, "i");

    // Taking getter's "body".
    var getterBody = Expression.Property(instanceType, property);

    // Cast to a generic Object.
    var body = Expression.TypeAs(getterBody, typeof(Object));

    // Build the expression.
    var exp = Expression.Lambda<Func<MyAbstractClass<T>, Object>>(body, instanceType);
    return exp.Compile();
}

就像预期一样,我得到以下例外:

  

“MyConcreteClass”类型的ParameterExpression不能用于   委托“MyAbstractClass&lt; MyConcreteType&gt;”类型的参数。

有没有办法“强迫”这种铸造?提前谢谢。

2 个答案:

答案 0 :(得分:12)

如果我正确理解你的问题,你想创建一个像这样的lambda表达式:

Func<MyAbstractClass<T>, Object> f = i => ((MyConcreteClass)i).SomeProperty;

除非您想提供哪个属性SomeProperty作为参数。好吧,如果要以编程方式构建该表达式,则必须完全相同:使用表达式参数i(类型为MyAbstractClass<T>),将其强制转换为MyConcreteClass,然后访问属性{ {1}}。{/ p>

SomeProperty

话虽如此,我完全不知道你为什么要这样做,所以你最好确定这是你想要做的事情,没有更好的办法做你真正想做的事情

答案 1 :(得分:0)

您不应该从泛型类型构建实例类型吗?

var genericType = typeof(MyAbstractClass<>).MakeGenericType(property.DeclaringType);
var instanceType = Expression.Parameter(genericType , "i");