C# Expression Tree to call base class property get method
.net-4.5, c#, expression-trees, reflection
Solution
You need to use property itself and not Getter method for it:
foreach (var property in properties)
{
Expression.Property(
Expression.ConvertChecked( inputObject, property.DeclaringType ),
property);
}
Basically you need to use this Property method instead of this overloaded Property method
UPDATE
For GetGetMethod approach - If `var objectType` equal to `A` type, then it works. If it equal to `B` type, then it doesn't work.
My guess, that the problem is in `property.DeclaringType`. For both cases it's `A` type, as property declared in it. But this code will return different `ReflectedType` for the same property:
var reflectingTypeForA = typeof(A).GetProperty("MyString").GetGetMethod().ReflectedType;
var reflectingTypeForB = typeof(B).GetProperty("MyString").GetGetMethod().ReflectedType;
For `A` it returns `A`, and for `B` type it returns `B`. My guess is that for `B` case Expression.Property logic checks that `property.DeclaringType` is `A`, but GetGetMethod has `ReflectedType` equal to `B`, so it thinks that it's property of another object. I haven't any proofs for that, but only these members are different between two GetGetMethod calls
UPDATE2
Here is a code that used by Expression.Property(MethodInfo method):
private static PropertyInfo GetProperty(MethodInfo mi)
{
Type type = mi.DeclaringType;
BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic;
flags |= (mi.IsStatic) ? BindingFlags.Static : BindingFlags.Instance;
PropertyInfo[] props = type.GetProperties(flags);
foreach (PropertyInfo pi in props)
{
if (pi.CanRead && CheckMethod(mi, pi.GetGetMethod(true)))
{
return pi;
}
if (pi.CanWrite && CheckMethod(mi, pi.GetSetMethod(true)))
{
return pi;
}
}
throw new SomeException();
}
private static bool CheckMethod(MethodInfo method, MethodInfo propertyMethod) {
if (method == propertyMethod) {
return true;
}
// If the type is an interface then the handle for the method got by the compiler will not be the
// same as that returned by reflection.
// Check for this condition and try and get the method from reflection.
Type type = method.DeclaringType;
if (type.IsInterface && method.Name == propertyMethod.Name && type.GetMethod(method.Name) == propertyMethod) {
return true;
}
return false;
}
The problem is in this line:
if (method == propertyMethod) {
return true;
}
When you get MethodInfo by GetGetMethod from Type `A`, it's different than MethodInfo from Type `B`, and this check returns false. Such example also returns false:
var propertyAGetter = typeof(A).GetProperty("MyString").GetGetMethod();
var propertyBGetter = typeof(B).GetProperty("MyString").GetGetMethod();
bool areTheSame = propertyAGetter == propertyBGetter; // it equals to false
Problem
I have built an expression tree that derives parameters from a class and invokes them to set values in another class. It works very well for most types, but it fails on a derived type. If I have: ``` public class A { public string MyString {get; set;} } ``` and ``` public class B : A { } ``` If I use this Expression Tree code (where `value` is the derived instance): ``` // Get the type of the object for caching and ExpressionTree purposes var objectType = value.GetType(); // Define input parameter var inputObject = Expression.Parameter( typeof( object ), "value" ); var properties = objectType.GetProperties( BindingFlags.Instance | BindingFlags.Public ); foreach (var property in properties) { Expression.Property( Expression.ConvertChecked( inputObject, property.DeclaringType ), property.GetGetMethod() ) } ``` I will receive this exception: ``` {System.ArgumentException: The method 'My.Namespace.A.get_MyString' is not a property accessor at System.Linq.Expressions.Expression.GetProperty(MethodInfo mi)... ``` What am I doing wrong here?