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?

Original source

Related problems