Skip to content

MethodInfo objects for same method are not equal #67989

@atykhyy

Description

@atykhyy

Description

In some cases, MethodInfo objects that refer to the same method but are obtained in different ways (reflection vs delegate creation, i.e. ldftn IL instruction) do not compare equal, and have different hash codes. DeclaringType and MetadataToken properties of the two MethodInfos are the same, but their MethodHandles are different. This happens when the method is declared in a value type, but not if it is declared in a reference type. This is very inconvenient because this means that MethodInfos cannot be used as dictionary keys.

Reproduction Steps

MWE:

using System;
using System.Linq.Expressions;
static class Program
{
    static void Main()
    {
        var m1 = ((MethodCallExpression)((Expression<Action>)(() => new C().M())).Body).Method;
        var m2 = new Action(new C().M).Method;
        Console.WriteLine(m1.MetadataToken == m2.MetadataToken); // 'true'
        Console.WriteLine(m1.DeclaringType == m2.DeclaringType); // 'true'
        Console.WriteLine(m1.GetHashCode() == m2.GetHashCode()); // 'true' if C is class, 'false' if C is struct
        Console.WriteLine(m1.Equals(m2)); // 'true' if C is class, 'false' if C is struct
    }
}

struct C { internal void M() {} }

Expected behavior

I expected MethodInfo objects referring to the same method to compare equal.

Actual behavior

In some cases, MethodInfo objects that refer to the same method but are obtained in different ways (reflection vs delegate creation, i.e. ldftn IL instruction) do not compare equal, and have different hash codes.

Regression?

No response

Known Workarounds

No response

Configuration

Windows 10 21H2 x64
Microsoft (R) Visual C# Compiler version 3.11.0-4.21403.6 (ae1fff34)
This behavior is the same in net461 (4.8.4470.0), netcoreapp3.1 (3.1.23), net5.0 (5.0.12) and net6.0 (6.0.1).

Other information

No response

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions