Here is a simple application that prints the signature of the MethodCallExpression method:
using System; using System.Linq; using System.Linq.Expressions; class A { public virtual void Foo() { } } class B : A { public override void Foo() { } } class C : B { public override void Foo() { } } class Program { static void Main(string[] args) { PrintMethod<A>(a => a.Foo()); PrintMethod<B>(b => b.Foo()); PrintMethod<C>(c => c.Foo()); Console.Read(); } static void PrintMethod<T>(Expression<Action<T>> expression) { var body = (MethodCallExpression)expression.Body; var method1 = body.Method; var method2 = typeof(T).GetMethod(body.Method.Name, body.Method.GetParameters().Select(p => p.ParameterType).ToArray()); Console.WriteLine("body.Method -> " + method1.DeclaringType.ToString() + " - " + method1.ToString()); Console.WriteLine("typeof(T).GetMethod -> " + method2.DeclaringType.ToString() + " - " + method2.ToString()); } }
I expect the program to be printed:
body.Method -> A - Void Foo() typeof(T).GetMethod -> A - Void Foo() body.Method -> B - Void Foo() * typeof(T).GetMethod -> B - Void Foo() body.Method -> C - Void Foo() * typeof(T).GetMethod -> C - Void Foo()
But instead, it produces:
body.Method -> A - Void Foo() typeof(T).GetMethod -> A - Void Foo() body.Method -> A - Void Foo() * typeof(T).GetMethod -> B - Void Foo() body.Method -> A - Void Foo() * typeof(T).GetMethod -> C - Void Foo()
When the Method property is MethodCallExpression for the inherited MethodCallExpression it always returns A MethodInfo (root class).
However, in Visual Studio and the “Go To Definition” of each of the calls to Foo() I take on each of the overridden methods as expected.
Why MethodCallExpression.Method behave like this? Is there anything in the spec about this? Why is there a mismatch between VS and the Method property? I tested with .NET 4.0 and 4.5.
source share