Skip to content

Commit 5578c94

Browse files
committed
Add fix for generic method case
1 parent 04c73ea commit 5578c94

File tree

2 files changed

+26
-3
lines changed

2 files changed

+26
-3
lines changed

src/coreclr/vm/genmeth.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1236,12 +1236,11 @@ MethodDesc::FindOrCreateAssociatedMethodDesc(MethodDesc* pDefMD,
12361236
if (methodInst.GetNumArgs() != pMethod->GetNumGenericMethodArgs())
12371237
COMPlusThrow(kArgumentException);
12381238

1239-
// we base the creation of an unboxing stub on whether the original method was one already
1240-
// that keeps the reflection logic the same for value types
1239+
// we need unboxing stubs for virtual methods on value types
12411240
pInstMD = MethodDesc::FindOrCreateAssociatedMethodDesc(
12421241
pMethod,
12431242
pMT,
1244-
pMethod->IsUnboxingStub(),
1243+
instType.IsValueType() && pMethod->IsVirtual(),
12451244
methodInst,
12461245
FALSE, /* no allowInstParam */
12471246
TRUE /* force remotable method (i.e. inst wrappers for non-generic methods on generic interfaces) */);

src/libraries/System.Runtime/tests/System/DelegateTests.cs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -452,10 +452,34 @@ public static void SameMethodObtainedViaDelegateAndReflectionAreSameForStruct()
452452
Assert.True(m1.Equals(m2));
453453
}
454454

455+
[Fact]
456+
public static void SameGenericMethodObtainedViaDelegateAndReflectionAreSameForClass()
457+
{
458+
var m1 = ((MethodCallExpression)((Expression<Action>)(() => new ClassG().M<string, object>())).Body).Method;
459+
var m2 = new Action(new ClassG().M<string, object>).Method;
460+
Assert.True(m1.Equals(m2));
461+
Assert.True(m1.GetHashCode().Equals(m2.GetHashCode()));
462+
Assert.Equal(m1.MethodHandle.Value, m2.MethodHandle.Value);
463+
}
464+
465+
[Fact]
466+
public static void SameGenericMethodObtainedViaDelegateAndReflectionAreSameForStruct()
467+
{
468+
var m1 = ((MethodCallExpression)((Expression<Action>)(() => new StructG().M<string, object>())).Body).Method;
469+
var m2 = new Action(new StructG().M<string, object>).Method;
470+
Assert.True(m1.Equals(m2));
471+
Assert.True(m1.GetHashCode().Equals(m2.GetHashCode()));
472+
Assert.Equal(m1.MethodHandle.Value, m2.MethodHandle.Value);
473+
}
474+
455475
class Class { internal void M() { } }
456476

457477
struct Struct { internal void M() { } }
458478

479+
class ClassG { internal void M<Key, Value>() { } }
480+
481+
struct StructG { internal void M<Key, Value>() { } }
482+
459483
private delegate void IntIntDelegate(int expected, int actual);
460484
private delegate void IntIntDelegateWithDefault(int expected, int actual = 7);
461485

0 commit comments

Comments
 (0)