当从实例获取Type时,MethodInfo总是null

本文关键字:MethodInfo 总是 null Type 实例 获取 | 更新日期: 2023-09-27 18:18:26

有人能解释一下我,为什么这里我得到正确的MethodInfo:

MethodInfo mi = typeof(ContextTimerMode).GetMethod(_vo.Phase, BindingFlags.Instance | BindingFlags.NonPublic);
if (mi != null)
{
    mi.Invoke(this, new object[] { btns, vo });
}

而试图得到它直接从实例返回总是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 });
}

以上代码来自ContextTimerMode

this是以ContextTimerMode为基类的类;

实际上我找不到它返回null的原因,因为我使用第二种方法,我正在调试并确保_vo.Phase字符串有正确的方法名称,所以我尝试了第一种方法,它成功了。

也在调试this时显示this不是ContextTimerMode的实例,而是具有ContextTimerMode基础的类型-所以这就是为什么我尝试使用(this as ContextTimerMode).GetType()

当从实例获取Type时,MethodInfo总是null

这是因为即使你这样做:

(this as ContextTimerMode).GetType()

结果类型将不是 ContextTimerMode,而是继承自ContextTimerMode的类型(因此,this的实际类型,与this.GetType()相同)。GetType()总是返回实际类型,即使你在声明为基类型的变量上使用它。你试图获得私有的,该类型的实例方法。您继承的类型实际上不包含此方法,因此GetMethod正确返回null。

如果你想解决这个问题,你可以手动遍历层次结构,像这样:

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;
}

关键字this是多余的。你可以在内部使用GetType(),它会引用你的类。

_vo.Phase

必须是正确的大小写,你不需要BindingFlags.Instance。我会删除BindingFlags。NonPublic,并将方法访问修饰符更改为public,看看GetMethod()是否真的能找到它。

您总是可以使用GetMethods()枚举类中可用的方法。甚至可以使用linq查询来获取你想要的MethodInfo对象