@@ -562,9 +562,6 @@ private static void InferExplicitInterfaceImplementations(TypeDefinition type, R
562
562
if ( Utf8String . IsNullOrEmpty ( method . Name ) )
563
563
continue ;
564
564
565
- // Explicit interface implementation
566
- // Note: This does not handle all cases.
567
- // Specifically, it does not handle the case where the interface has multiple methods with the same name.
568
565
var periodLastIndex = method . Name . LastIndexOf ( '.' ) ;
569
566
if ( periodLastIndex < 0 || ! method . IsPrivate || ! method . IsVirtual || ! method . IsFinal || ! method . IsNewSlot )
570
567
{
@@ -578,21 +575,46 @@ private static void InferExplicitInterfaceImplementations(TypeDefinition type, R
578
575
: [ ] ;
579
576
var interfaceType = AsmResolverUtils . TryLookupTypeSignatureByName ( interfaceName , genericParameterNames ) ;
580
577
578
+ if ( interfaceType is null )
579
+ continue ;
580
+
581
+ var ambiguous = false ;
581
582
IMethodDefOrRef ? interfaceMethod = null ;
582
- var underlyingInterface = interfaceType ? . GetUnderlyingTypeDefOrRef ( ) ;
583
+ var underlyingInterface = interfaceType . GetUnderlyingTypeDefOrRef ( ) ;
583
584
foreach ( var interfaceMethodDef in ( underlyingInterface as TypeDefinition ) ? . Methods ?? [ ] )
584
585
{
585
586
if ( interfaceMethodDef . Name != methodName )
586
587
continue ;
587
588
588
589
if ( interfaceMethod is not null )
589
590
{
590
- // Ambiguity. Checking the method signature would be required to disambiguate.
591
+ // Ambiguity. Checking the method signature will be required to disambiguate.
591
592
interfaceMethod = null ;
593
+ ambiguous = true ;
592
594
break ;
593
595
}
594
596
595
- interfaceMethod = new MemberReference ( interfaceType ? . ToTypeDefOrRef ( ) , interfaceMethodDef . Name , interfaceMethodDef . Signature ) ;
597
+ // This has the implicit assumption that the method signatures match.
598
+ // This is a reasonable assumption because there's no other method to match (with this name).
599
+ interfaceMethod = new MemberReference ( interfaceType . ToTypeDefOrRef ( ) , interfaceMethodDef . Name , interfaceMethodDef . Signature ) ;
600
+ }
601
+
602
+ if ( ambiguous )
603
+ {
604
+ // Ambiguities are very rare, so we only bother signature checking when we have to.
605
+
606
+ var genericContext = GenericContext . FromType ( interfaceType ) ;
607
+ foreach ( var interfaceMethodDef in ( underlyingInterface as TypeDefinition ) ? . Methods ?? [ ] )
608
+ {
609
+ if ( interfaceMethodDef . Name != methodName )
610
+ continue ;
611
+
612
+ if ( SignatureComparer . Default . Equals ( method . Signature , interfaceMethodDef . Signature ? . InstantiateGenericTypes ( genericContext ) ) )
613
+ {
614
+ interfaceMethod = new MemberReference ( interfaceType ? . ToTypeDefOrRef ( ) , interfaceMethodDef . Name , interfaceMethodDef . Signature ) ;
615
+ break ;
616
+ }
617
+ }
596
618
}
597
619
598
620
if ( interfaceMethod != null )
@@ -601,5 +623,4 @@ private static void InferExplicitInterfaceImplementations(TypeDefinition type, R
601
623
}
602
624
}
603
625
}
604
-
605
626
}
0 commit comments