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");
精彩评论