3

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!

Community
  • 1
  • 1
Sinix
  • 1,306
  • 9
  • 46
  • Does your question is that why first compare return false and another compare return false ? – dotnetstep Dec 25 '14 at 08:19
  • Results are 'false', 'true', not 'false', false:) The question was about the first one. Jon Skeet already gave complete answer below. Thanks! – Sinix Dec 25 '14 at 08:34
  • Whoops, it looks I was wrong with 'do not mark as duplicate'. [There is](http://stackoverflow.com/q/12765804/318263) similar question, missed it. – Sinix Dec 25 '14 at 10:24

1 Answers1

6

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
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194