【问题标题】:How to determine if the MethodInfo is an override of the base method如何确定 MethodInfo 是否是基方法的覆盖
【发布时间】:2009-06-11 17:03:35
【问题描述】:

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

例如:

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

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

相关问题

Is it possible to tell if a .NET virtual method has been overriden in a derived class?

【问题讨论】:

    标签: c# .net reflection overriding methodinfo


    【解决方案1】:

    检查其DeclaringType 属性。

    if (methodInfo.DeclaringType == typeof(Foo)) {
       // ...
    }
    

    【讨论】:

    • 如果被检查的方法也是一个抽象方法,这将不起作用。这是explanation。
    【解决方案2】:

    除了使用反射之外,一种更快的方法是使用委托! 尤其是新版本的框架,运行速度真的很快。

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

    【讨论】:

    • 太棒了!我以前在任何地方都没有见过这个技巧。你是怎么想到的?
    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

      您必须检查MemberInfo 对象的DeclaringType 属性是否(DeclaringType 实际上得到声明此成员的类)等于 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;
          }
      }
      

      【讨论】:

      • 其实方法可以重新抽象,即abstract override。 (sharplab)
      • 也许你在谈论一些不同的东西——OP询问如何检测一个方法是一个覆盖,而不是如何检测一个方法被覆盖。
      • 关于抽象方法:假设Animal 覆盖ToString(),然后Mammal 具有abstract override 的ToString()。换句话说,Mammal 重新抽象该方法,要求它的具体子类型在某个时候重新实现它。我们会考虑从Mammal 的角度重写该方法吗?当然,这取决于我们的定义。我们可以肯定地说的一件事是,与 original 实现(恰好是 Object.ToString())相比,该方法绝对被覆盖。
      猜你喜欢
      • 2011-06-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-29
      • 1970-01-01
      • 2012-10-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多