从实例

时间:2016-11-16 16:20:10

标签: c# inheritance reflection

有人可以解释一下,为什么我会得到正确的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的类型时 - 这就是我尝试使用{的原因{1}} ...

2 个答案:

答案 0 :(得分:4)

这是因为即使你这样做了:

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

答案 1 :(得分:0)

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

_vo.Phase

必须是正确的大小写,并且您不需要BindingFlags.Instance。我也会删除BindingFlags.NonPublic,并将方法访问修饰符更改为public,以查看GetMethod()是否可以实际找到它。

您始终可以使用GetMethods()枚举类中的可用方法。甚至可以使用linq查询来获取所需的MethodInfo对象。