2009-06-11 4 views
12

Tôi đang cố gắng để xác định nếu đối tượng MethodInfo mà tôi nhận được từ một cuộc gọi GetMethod trên một thể hiện kiểu được thực hiện bởi loại hoặc bởi cơ sở của nó.Làm thế nào để xác định nếu MethodInfo là một ghi đè của phương pháp cơ sở

Ví dụ:

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

phương pháp ToString có thể được thực hiện trong lớp Foo hay không. Tôi muốn biết nếu tôi đang thực hiện foo?

câu hỏi liên quan

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

Trả lời

19

Kiểm tra tài sản DeclaringType của nó.

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

+1 Đó là một :) –

+0

này sẽ không hoạt động nếu các phương pháp kiểm tra cũng là một bản tóm tắt. Đây là [giải thích] (https://stackoverflow.com/a/45560768/5259296). –

1

Bạn sẽ muốn xem thuộc tính DeclaringType. Nếu phương thức ToString xuất phát từ Foo, thì DeclaringType sẽ là kiểu Foo.

2

Thay vì sử dụng phản xạ, cách nhanh hơn là sử dụng các đại biểu! Đặc biệt trong phiên bản mới của khuôn khổ hoạt động thực sự nhanh chóng.

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

Bạn cần phải kiểm tra xem DeclaringType tài sản của MemberInfo đối tượng (DeclaringType thực sự được lớp mà tuyên bố thành viên này) bằngReflectedType tài sản (mà được các đối tượng lớp được sử dụng để có được điều này bản sao của MemberInfo).

Bên cạnh đó, bạn cũng phải kiểm tra thuộc tính IsAbstract. Nếu nó là true, sau đó phương pháp kiểm tra chắc chắn không ghi đè là, bởi vì "là trừu tượng" có nghĩa là thành viên này là một tuyên bố mới mà không thể có nó thực hiện (cơ thể) trong lớp hiện tại (nhưng chỉ trong thay vào đó là các lớp dẫn xuất).

Dưới đây là một ví dụ về việc sử dụng các phương pháp khuyến nông cung cấp dưới đây:

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

Phương pháp mở rộng:

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

Thực ra, một phương thức ** có thể ** được trích xuất, tức là 'ghi đè trừu tượng'. ([sharplab] (https://sharplab.io/#v2:EYLgtghgzgLgpgJwD4AEDMACFAmDAhaOAYQBtooBYAKAG9qMGtMA3ASwRgFcISsAWDAGUA9mDgBZODAAWwgCYAKAJT1GdKowwBfajqrV0GCMFgIIAYxhZcAJTjHTFmKwB2Ac1LkMIfIU9RKWlUGQwcYM0sMYWZEBFY5OH4hUQkpWUUlAG5dIA===)) – jnm2

+0

Có lẽ bạn đang nói về cái gì đó OP though- khác nhau hỏi làm thế nào để phát hiện rằng một phương pháp là ghi đè, không làm thế nào để phát hiện rằng một phương thức bị ghi đè. – jnm2