@@ -562,9 +562,6 @@ private static void InferExplicitInterfaceImplementations(TypeDefinition type, R
562562 if ( Utf8String . IsNullOrEmpty ( method . Name ) )
563563 continue ;
564564
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.
568565 var periodLastIndex = method . Name . LastIndexOf ( '.' ) ;
569566 if ( periodLastIndex < 0 || ! method . IsPrivate || ! method . IsVirtual || ! method . IsFinal || ! method . IsNewSlot )
570567 {
@@ -578,21 +575,46 @@ private static void InferExplicitInterfaceImplementations(TypeDefinition type, R
578575 : [ ] ;
579576 var interfaceType = AsmResolverUtils . TryLookupTypeSignatureByName ( interfaceName , genericParameterNames ) ;
580577
578+ if ( interfaceType is null )
579+ continue ;
580+
581+ var ambiguous = false ;
581582 IMethodDefOrRef ? interfaceMethod = null ;
582- var underlyingInterface = interfaceType ? . GetUnderlyingTypeDefOrRef ( ) ;
583+ var underlyingInterface = interfaceType . GetUnderlyingTypeDefOrRef ( ) ;
583584 foreach ( var interfaceMethodDef in ( underlyingInterface as TypeDefinition ) ? . Methods ?? [ ] )
584585 {
585586 if ( interfaceMethodDef . Name != methodName )
586587 continue ;
587588
588589 if ( interfaceMethod is not null )
589590 {
590- // Ambiguity. Checking the method signature would be required to disambiguate.
591+ // Ambiguity. Checking the method signature will be required to disambiguate.
591592 interfaceMethod = null ;
593+ ambiguous = true ;
592594 break ;
593595 }
594596
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+ }
596618 }
597619
598620 if ( interfaceMethod != null )
@@ -601,5 +623,4 @@ private static void InferExplicitInterfaceImplementations(TypeDefinition type, R
601623 }
602624 }
603625 }
604-
605626}
0 commit comments