Polymorphism in Expression trees
While trying to be extra-clever today, I found a potential nasty issue when dealing with strongly-typed reflection. Suppose I have a simple hierarchy of objects:
public abstract class Base { public abstract string Foo { get; } } public class Child : Base { public override string Foo { get { return "asdf"; } } }
An abstract base class and a child class that implements the one abstract member. Suppose now we want to do some strongly-typed reflection with the child type:
[Test] public void PolymorphicWeirdness() { Expression<Func<Child, object>> func = child => child.Foo; var body = (MemberExpression) func.Body; body.Member.DeclaringType.ShouldEqual(typeof (Child)); }
Many frameworks, AutoMapper being one of them, take advantage of this strongly-typed reflection to get to MemberInfo information on the property or method used in the expression. Unfortunately, the above test fails. Instead of the MemberInfo’s DeclaringType being “Child”, it’s “Base”.
If I’m using Expressions to do things like interrogate the MemberInfo for things like custom attributes, I won’t be getting the whole story here. Lots of other OSS tools use Expressions quite a bit, so I’m very curious to see what those tools do with this behavior. Note, it’s only the Expression tree with the polymorphism issue. Once you compile the Expression, all of the normal CLR resolution rules are applied.
This seems like someone would have written about this issue by now, so I’m off to do some sleuthing to see how others deal with this.