运行时方法信息的相等性:有bug吗?

3
让我们开始吧:

首先:
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();
    }
}

这里有两个不同的MethodInfo实例,都包含相同的方法句柄。以下是等于运算符源代码

(在ideone上尝试在线翻译

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实例都被缓存,并且对于相同方法永远不会有两个不同的实例存在。如果是这种情况,显然出现了某些问题。
有人知道这种行为背后的原因吗?
附言:请不要标记为[duplicate],这个问题不是关于“如何比较?”的。例如,这个问题已经被回答了多次,可以在这里这里找到答案。
谢谢!

你的问题是为什么第一次比较返回 false,而另一个比较也返回 false 吗? - dotnetstep
结果是“false”,“true”,而不是“false”,false :) 这个问题是关于第一个的。Jon Skeet已经在下面给出了完整的答案。谢谢! - Sinix
糟糕,看起来我在“不要标记为重复”方面是错误的。有一个类似的问题,我错过了它。这里是链接。 - Sinix
1个回答

6

我相信你对此的推断是正确的——两个RuntimeMethodInfo实例可以通过引用相等进行比较。但你对它已经失效的假设是不正确的。

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

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接