The property you are trying to access is not IBar.X , it IFoo.X The Expression.Property method expects an actual type that declares a property, not a subtype. If you are not sure, try the following:
var prop = typeof(IBar).GetProperty("X");
It returns null (just because IBar is an interface, it will work for a class)
I think the easiest way to make it work is to create a helper method to resolve the actual property, returning the type hierarchy recursively:
private PropertyInfo GetProperty(Type type, string propertyName) { PropertyInfo prop = type.GetProperty(propertyName); if (prop == null) { var baseTypesAndInterfaces = new List<Type>(); if (type.BaseType != null) baseTypesAndInterfaces.Add(type.BaseType); baseTypesAndInterfaces.AddRange(type.GetInterfaces()); foreach(Type t in baseTypesAndInterfaces) { prop = GetProperty(t, propertyName); if (prop != null) break; } } return prop; }
Then you can rewrite PropertyOfProperty as follows:
private static MemberExpression PropertyOfProperty(Expression expr, string propertyName) { return propertyName .Split('.') .Aggregate<string, MemberExpression>( expr, (current, property) => Expression.Property( current, GetProperty(current.Type, property))); }
source share