-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Description
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