18

我正在尝试确定从类型实例上的 GetMethod 调用获得的 MethodInfo 对象是由该类型实现还是由它的基实现。

例如:

Foo foo = new Foo();
MethodInfo methodInfo = foo.GetType().GetMethod("ToString",BindingFlags|Instance);

ToString 方法可以在 Foo 类中实现,也可以不在。我想知道我是否得到了 foo 实现?

相关问题

是否可以判断.NET 虚拟方法是否已在派生类中被覆盖?

4

4 回答 4

21

检查其DeclaringType属性。

if (methodInfo.DeclaringType == typeof(Foo)) {
   // ...
}
于 2009-06-11T17:06:05.987 回答
5

代替使用反射,一种更快的方法是使用委托!尤其是在新版本的框架中,运行速度真的很快。

    public delegate string ToStringDelegate();

    public static bool OverridesToString(object instance)
    {
        if (instance != null)
        {
            ToStringDelegate func = instance.ToString;
            return (func.Method.DeclaringType == instance.GetType());
        }
        return false;
    }
于 2011-08-13T20:20:23.087 回答
1

您需要查看 DeclaringType 属性。如果 ToString 方法来自 Foo,则 DeclaringType 将是 Foo 类型。

于 2009-06-11T17:09:57.460 回答
1

您必须检查对象DeclaringType的属性MemberInfoDeclaringType实际上获取声明此成员的类是否等于 ReflectedType属性(获取用于获取此实例的类对象MemberInfo)。

除此之外,您还必须检查财产IsAbstract如果true那么被检查的方法肯定不会被覆盖,因为“被抽象”意味着这个成员是一个新的声明,它不能在当前类中实现(body)(但只能在派生类中)。

以下是使用下面提供的扩展方法的示例:

Student student = new Student
{
    FirstName = "Petter",
    LastName = "Parker"
};

bool isOverridden = student.GetType()
    .GetMethod(
        name: nameof(ToString),
        bindingAttr: BindingFlags.Instance | BindingFlags.Public,
        binder: null,
        types: Type.EmptyTypes,
        modifiers: null
    ).IsOverridden(); // ExtMethod

if (isOverridden)
{
    Console.Out.WriteLine(student);
}

扩展方法:

using System.Reflection;

public static class MethodInfoHelper
{
    /// <summary>
    ///     Detects whether the given method is overridden.
    /// </summary>
    /// <param name="methodInfo">The method to inspect.</param>
    /// <returns><see langword="true" /> if method is overridden, otherwise <see langword="false" /></returns>
    public static bool IsOverridden(this MethodInfo methodInfo)
    {
        return methodInfo.DeclaringType == methodInfo.ReflectedType
               && !methodInfo.IsAbstract;
    }
}
于 2017-08-08T06:26:41.277 回答