14

I have the following class tree:

public class A
{
    public static object GetMe(SomeOtherClass something)
    {
        return something.Foo();
    }
}

public class B:A
{
    public static new object GetMe(SomeOtherClass something)
    {
        return something.Bar();
    }
}

public class C:B
{

}

public class SomeOtherClass
{

}

Given SomeOtherClass parameter = new SomeOtherClass()) this works:

typeof(B).GetMethod("GetMe", new Type[] { typeof(SomeOtherClass) })).Invoke(null, parameter));

But this:

typeof(C).GetMethod("GetMe", new Type[] { typeof(SomeOtherClass) })).Invoke(null, parameter));

throws a NullReferenceException, while I wish it would call the exact same method than above.

I've tried several binding flags to no avail. Any help?

the Tin Man
  • 158,662
  • 42
  • 215
  • 303
Sebastián Vansteenkiste
  • 2,234
  • 1
  • 19
  • 29

2 Answers2

28

You should use one the overloads taking a BindingFlags parameter, and include FlattenHierarchy.

Specifies that public and protected static members up the hierarchy should be returned. Private static members in inherited classes are not returned. Static members include fields, methods, events, and properties. Nested types are not returned.

(Edited to remove the point about private static methods, now the question has been changed to make them public.)

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • The methods are public static, I misstyped the question (and I thought I had proof read it D:). Thanks still! – Sebastián Vansteenkiste Sep 11 '12 at 00:15
  • 1
    @SebastiánVansteenkiste: In that case, just changing the binding flags to include FlattenHierarchy (and static, and public) should be fine. – Jon Skeet Sep 11 '12 at 00:16
  • Many thanks! For the future generations then: `typeof(C).GetMethod("GetMe", BindingFlags.FlattenHierarchy | BindingFlags.Public | BindingFlags.Static, null, new Type[] { typeof(SomeOtherClass) }, null)).Invoke(null, parameter));` did the trick. – Sebastián Vansteenkiste Sep 11 '12 at 00:26
  • What if you don't want the parent methods? Parent methods are being returned for me even without specifying FlattenHierarchy. The derived class is abstact, btw – DevDave Sep 03 '13 at 12:49
  • 1
    @DevDave: That surprises me - it sounds like it's probably best to ask about that in a separate question, with a short but complete program demonstrating the problem. – Jon Skeet Sep 03 '13 at 12:51
  • 1
    I found that specifying BindingFlags.DeclaredOnly solved this for me. Not sure why it was returning derived methods by default. I was using a Controller Class that derived from an abstract Controller Class. – DevDave Sep 03 '13 at 13:01
  • 1
    @DevDave using BindingFlags.DeclaredOnly (in conjunction with BindingFlags.Instance and BindingFlags.Public) did the trick for me as well when I was getting inherited methods from Object (like ToString, Equals, GetType, and GetHashCode) when calling GetMethods on my reflected type. – mkmurray Dec 11 '13 at 18:19
6

You need to pass BindingFlags.FlattenHierarchy flag to GetMethod in order to search up the hierarchy:

typeof(C).GetMethod("GetMe", BindingFlags.FlattenHierarchy, null, new Type[] { typeof(SomeOtherClass) }, null)).Invoke(null, parameter));
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523