Jerry Switalski Jerry Switalski - 24 days ago 7
C# Question

MethodInfo always null when geting Type from instance

Can someone explain me, why here I get the correct

MethodInfo
:

MethodInfo mi = typeof(ContextTimerMode).GetMethod(_vo.Phase, BindingFlags.Instance | BindingFlags.NonPublic);

if (mi != null)
{
mi.Invoke(this, new object[] { btns, vo });
}


While trying to get it directly from instance returns always null?:

MethodInfo mi = (this as ContextTimerMode).GetType().GetMethod(_vo.Phase, BindingFlags.Instance | BindingFlags.NonPublic);

// mi always null
if (mi != null)
{
mi.Invoke(this, new object[] { btns, vo });
}


The code above is from
ContextTimerMode
.

this
is a class that has
ContextTimerMode
as base class;

Actually I couldn't find a reason why it returns a null for sometime as I was using second method and I was debugging and making sure
_vo.Phase
string has correct name of method so I tried first method and it worked out.

Also when debugging
this
was showing that
this
is instance not of
ContextTimerMode
but a type that has a base of
ContextTimerMode
- so that is why I tried with
(this as ContextTimerMode).GetType()
...

Evk Evk
Answer

That is because even if you do this:

(this as ContextTimerMode).GetType()

resulting type will not be ContextTimerMode, but will be the type inherited from ContextTimerMode (so, actual type of this, same as if you did this.GetType()). GetType() always returns actual type, even if you use it on variable declared as some base type. You are trying to get private, instance method of that type. Your inherited type really does not contain this method, so GetMethod correctly returns null.

If you want to work around this, you can manually walk hierarchy, like this:

static MethodInfo GetMethod(Type type, string methodName, BindingFlags flags) {
    var mi = type.GetMethod(methodName, flags);
    if (mi != null)
        return mi;
    if (type.BaseType != null)
        return GetMethod(type.BaseType, methodName, flags);
    return null;
}