开发者

Lambda Expression: cast parameter to base type

I'd like to "wrap" the getter function for a specific property that is part of a specific type. I have an abstract class, defined like following:

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

Well, suppose I've a开发者_开发技巧 concrete class like the following one:

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

And now, the helper method that should return a wrapper for the getter method:

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();
}

Just like expected, I get the following exception:

ParameterExpression of type 'MyConcreteClass' cannot be used for delegate parameter of type 'MyAbstractClass<MyConcreteType>'.

Is there a way to "force" this kind of casting? Thanks in advance.


If I understand your question correctly, you want to create a lambda expression like this:

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

Except you want to provide which property is SomeProperty as a parameter. Well, if you want to build that expression programmatically, you have to do exactly the same: have expression parameter i (of type MyAbstractClass<T>), cast it to MyConcreteClass and then access property SomeProperty of that.

public Func<MyAbstractClass<T>, Object> GetPropertyGetter(PropertyInfo property)
{
    var parameter = Expression.Parameter(typeof(MyAbstractClass<T>), "i");

    var cast = Expression.TypeAs(parameter, property.DeclaringType);

    var getterBody = Expression.Property(cast, property);

    var exp = Expression.Lambda<Func<MyAbstractClass<T>, Object>>(
        getterBody, parameter);

    return exp.Compile();
}

Having said that, I have absolutely no idea why would you want to do that, so you better be really sure this is what you want to do and that there isn't any better way of doing what you actually want to do.


Shouldn't you be building the instance type from the generic type?

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜