How to find all methods that are declared as virtual in c# using reflection?

For example

public class UserInfo {}

public interface IUser
{
  UserInfo Get(int id);
  string GetData(int id);
}

public class User : IUser
{
    public UserInfo Get(int id)
    {
        return null;
    }
    public virtual string GetData(int id)
    {
        return null;
    }
}

I tried the following but it returns true for both methods.

MethodInfo[] methods=typeof(User).GetMethods();
foreach(MethodInfo method in methods)
{
   if(method.IsVirtual)
   {
      Console.WriteLine(method.Name);
   }
}

Expected Output

GetData

Actual Output

Get
GetData

This link is some what similar but not working in my case: use-reflection-to-find-all-public-virtual-methods-and-provide-an-override

Upvotes: 0

Views: 454

Answers (2)

Troels Larsen
Troels Larsen

Reputation: 4631

Full, working sample:

class Program
{
    static void Main(string[] args)
    {
        MethodInfo[] methods = typeof(User).GetMethods();
        foreach (var method in methods)
        {
            if (method.IsVirtual && !method.IsFinal)
            {
                Console.WriteLine(method.Name);
            }
        }
        Console.ReadLine();
    }
}

public class User : IUser
{
    public string Get(int id)
    {
        // some codes
        return null;
    }
    public virtual string GetData(int id)
    {
        // I want to find this method declared as virtual
        return null;
    }
}

public interface IUser
{
    string Get(int id);
    string GetData(int id);
}

Output:

GetData
ToString
Equals
GetHashCode

Upvotes: 1

Jon Skeet
Jon Skeet

Reputation: 1500525

The problem is Get is a virtual method in that it implements IUser.Get and so is called using execution-time dispatch - I suspect, anyway. (You haven't given us a complete program, so I've had to guess.)

If you actually want "methods that can be overridden" you also need to check MethodBase.IsFinal. So just change your loop to:

foreach (MethodInfo method in methods)
{
   if (method.IsVirtual && !method.IsFinal)
   {
      Console.WriteLine(method.Name);
   }
}

Upvotes: 4

Related Questions