private static DefaultInterfaceMethodResolution ResolveInterfaceMethodToDefaultImplementationOnType(MethodDesc interfaceMethod, MetadataType currentType, out MethodDesc impl) { TypeDesc interfaceMethodOwningType = interfaceMethod.OwningType; MetadataType mostSpecificInterface = null; bool diamondCase = false; impl = null; MethodDesc interfaceMethodDefinition = interfaceMethod.GetMethodDefinition(); DefType[] consideredInterfaces; if (!currentType.IsInterface) { // If this is not an interface, only things on the interface list could provide // default implementations. consideredInterfaces = currentType.RuntimeInterfaces; } else { // If we're asking about an interface, include the interface in the list. consideredInterfaces = new DefType[currentType.RuntimeInterfaces.Length + 1]; Array.Copy(currentType.RuntimeInterfaces, consideredInterfaces, currentType.RuntimeInterfaces.Length); consideredInterfaces[consideredInterfaces.Length - 1] = (DefType)currentType.InstantiateAsOpen(); } foreach (MetadataType runtimeInterface in consideredInterfaces) { if (runtimeInterface == interfaceMethodOwningType) { // Also consider the default interface method implementation on the interface itself // if we don't have anything else yet if (mostSpecificInterface == null && !interfaceMethod.IsAbstract) { mostSpecificInterface = runtimeInterface; impl = interfaceMethodDefinition; } } else if (Array.IndexOf(runtimeInterface.RuntimeInterfaces, interfaceMethodOwningType) != -1) { // This interface might provide a default implementation MethodImplRecord[] possibleImpls = runtimeInterface.FindMethodsImplWithMatchingDeclName(interfaceMethod.Name); if (possibleImpls != null) { foreach (MethodImplRecord implRecord in possibleImpls) { if (implRecord.Decl == interfaceMethodDefinition) { // This interface provides a default implementation. // Is it also most specific? if (mostSpecificInterface == null || Array.IndexOf(runtimeInterface.RuntimeInterfaces, mostSpecificInterface) != -1) { mostSpecificInterface = runtimeInterface; impl = implRecord.Body; diamondCase = false; } else if (Array.IndexOf(mostSpecificInterface.RuntimeInterfaces, runtimeInterface) == -1) { diamondCase = true; } break; } } } } } if (diamondCase) { impl = null; return(DefaultInterfaceMethodResolution.Diamond); } else if (impl == null) { return(DefaultInterfaceMethodResolution.None); } else if (impl.IsAbstract) { impl = null; return(DefaultInterfaceMethodResolution.Reabstraction); } if (interfaceMethod != interfaceMethodDefinition) { impl = impl.MakeInstantiatedMethod(interfaceMethod.Instantiation); } return(DefaultInterfaceMethodResolution.DefaultImplementation); }