@@ -128,6 +128,11 @@ public static bool IsExtensionParameter(this ParameterInfo parameter)
128128 method . GetParameters ( ) . First ( ) == parameter ;
129129 }
130130
131+ public static bool IsExplicit ( this MemberInfo member )
132+ {
133+ return member . Name . Contains ( "." ) ;
134+ }
135+
131136 public static string GetPossibleExplicitName ( this MemberInfo member )
132137 {
133138 return $ "{ member . DeclaringType . NotNull ( ) . FullName . NotNull ( ) . Replace ( "+" , "." ) } .{ member . Name } ";
@@ -147,35 +152,53 @@ public static IEnumerable<MemberInfo> GetAllMembers(
147152 this Type buildType ,
148153 Func < MemberInfo , bool > filter ,
149154 BindingFlags bindingFlags ,
150- bool allowAmbiguity )
155+ bool allowAmbiguity ,
156+ bool filterQuasiOverridden = false )
151157 {
152- var interfaceMembers = buildType . GetInterfaces ( )
158+ var interfaceMembersByName = buildType . GetInterfaces ( )
153159 . SelectMany ( x => x . GetMembers ( bindingFlags ) )
154160 . Where ( filter )
155- . Where ( x => buildType . GetMember ( x . Name ) . SingleOrDefault ( ) == null ) . ToLookup ( x => x . Name ) ;
161+ . Where ( x => buildType . GetMember ( x . Name ) . SingleOrDefault ( ) == null ) . ToLookup ( x => x . GetDisplayShortName ( ) ) ;
156162 var classMembers = buildType
157163 . GetMembers ( bindingFlags )
158164 . Where ( filter )
159- . Where ( x => ! x . Name . Contains ( "." ) ) . ToDictionary ( x => x . Name ) ;
165+ . Where ( x => ! x . IsExplicit ( ) ) . ToDictionary ( x => x . Name ) ;
166+ var removeMembers = new List < MemberInfo > ( ) ;
160167
161- foreach ( var interfacePropertiesByName in interfaceMembers )
168+ foreach ( var interfaceMembers in interfaceMembersByName )
162169 {
163- var memberName = interfacePropertiesByName . Key ;
164- var memberType = interfacePropertiesByName . First ( ) . MemberType ;
170+ var memberName = interfaceMembers . Key ;
171+ var memberType = interfaceMembers . First ( ) . MemberType ;
165172 var classMember = classMembers . GetValueOrDefault ( memberName ) ;
166173
167- ControlFlow . Assert ( allowAmbiguity || interfacePropertiesByName . Count ( ) == 1 || classMember != null ,
174+ if ( filterQuasiOverridden && classMember == null && interfaceMembers . Count ( ) > 1 )
175+ {
176+ var orderedProperties = interfaceMembers
177+ . TSort ( x => interfaceMembers . Where ( y => y . DeclaringType . NotNull ( ) . IsAssignableFrom ( x . DeclaringType ) ) ) . ToList ( ) ;
178+
179+ var mostBaseType = orderedProperties . First ( ) . DeclaringType . NotNull ( ) ;
180+ var derivedTypes = orderedProperties . Skip ( 1 ) . Select ( x => x . DeclaringType ) ;
181+ if ( derivedTypes . All ( x => mostBaseType . IsAssignableFrom ( x ) ) )
182+ {
183+ removeMembers . AddRange ( orderedProperties . Take ( orderedProperties . Count - 1 ) ) ;
184+ continue ;
185+ }
186+ }
187+
188+ ControlFlow . Assert ( allowAmbiguity || interfaceMembers . Count ( ) == 1 || classMember != null ,
168189 new [ ] { $ "{ memberType } '{ memberName } ' must be implemented explicitly because it is inherited from multiple interfaces:" }
169- . Concat ( interfacePropertiesByName . Select ( x => $ " - { x . DeclaringType . NotNull ( ) . Name } ") )
190+ . Concat ( interfaceMembers . Select ( x => $ " - { x . DeclaringType . NotNull ( ) . Name } ") )
170191 . JoinNewLine ( ) ) ;
192+
171193 ControlFlow . Assert ( allowAmbiguity || classMember == null || classMember . IsPublic ( ) ,
172194 new [ ] { $ "{ memberType } '{ memberName } ' must be marked public to override inherited member from:" }
173- . Concat ( interfacePropertiesByName . Select ( x => $ " - { x . DeclaringType . NotNull ( ) . Name } ") )
195+ . Concat ( interfaceMembers . Select ( x => $ " - { x . DeclaringType . NotNull ( ) . Name } ") )
174196 . JoinNewLine ( ) ) ;
175197 }
176198
177199 return classMembers . Values
178- . Concat ( interfaceMembers . SelectMany ( x => x ) . Select ( x => x . GetImplementedOrInterfaceMember ( buildType ) ) )
200+ . Concat ( interfaceMembersByName . SelectMany ( x => x ) . Select ( x => x . GetImplementedOrInterfaceMember ( buildType ) ) )
201+ . Except ( removeMembers )
179202 . Where ( filter ) . ToList ( ) ;
180203 }
181204 }
0 commit comments