关于c#:runtimemethodinfo equality:bug?

RuntimeMethodInfo equality: bug?

让我们从以下内容开始:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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();
    }
}

(在Ideone网上尝试)

因此,有两个不相等的MethodInfo实例,都包含相同的方法句柄。这是等号运算符源:

1
2
3
4
5
6
7
8
9
10
11
12
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);
}

它看起来不像是一个意外的错误,至少在假设RuntimeMethodInfo的所有实例都已缓存并且同一方法将有两个不同的新实例之前。显然,在这种情况下,有些东西是坏的。

这行为背后有什么原因吗?

P.S.请勿标记为[副本],请:)问题不在于"如何比较?"。例如,这个问题在这里和这里被多次回答。

谢谢!


我相信你对它背后的推理的假设——两个RuntimeMethodInfo实例可以通过引用相等进行比较——是正确的。但你认为它坏了的假设是不正确的。

这里的两个MethodInfo对象是不同的,因为它们具有不同的ReflectedType属性:

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