RuntimeMethodInfo equality: bug?

Lets start with:

using System;

public class Program
{
    class A
    {
        public virtual void Do() { }
    }

    class B:A
    {
    }

    public static void Main()
    {
        var m1 = typeof(A).GetMethod("Do");
        var m2 = typeof(B).GetMethod("Do");

        Console.WriteLine("Methods are equal?\t\t{0}", m1 == m2);
        Console.WriteLine("Method handles are equal?\t{0}", m1.MethodHandle == m2.MethodHandle);

        Console.WriteLine("Done.");
        Console.ReadKey();
    }
}

(try it online at ideone)

So, there are two unequal MethodInfo instances, both containing the same method handle. Here's the equals operator source:

public static bool operator ==(MethodInfo left, MethodInfo right)
{
    if (ReferenceEquals(left, right))
        return true;

    if ((object)left == null || (object)right == null ||
        left is RuntimeMethodInfo || right is RuntimeMethodInfo) // <----??? 
    {
        return false;
    }
    return left.Equals(right);
}

It doesn't look like an accidental bug, at least until there was assumption that all instances of RuntimeMethodInfo are cached and there newer will be two different instances for the same method. In that case something is broken, obviously.

Any reasons behind this behavior, anyone?

P.S. Do not mark as a [duplicate], please:) The question is not about 'how to compare?'. That one was answered multiple times, here and here for example.

Thanks!

Jon Skeet
people
quotationmark

I believe your assumption for the reasoning behind it - that two RuntimeMethodInfo instances can be compared by reference equality - is correct. Your assumption that it's broken isn't correct though.

The two MethodInfo objects here are different, as they have different ReflectedType properties:

Console.WriteLine(m1.ReflectedType); // Program+A
Console.WriteLine(m2.ReflectedType); // Program+B

people

See more on this question at Stackoverflow