internal static Symbol GetRuntimeMember(NamedTypeSymbol declaringType, ref MemberDescriptor descriptor, SignatureComparer <MethodSymbol, FieldSymbol, PropertySymbol, TypeSymbol, ParameterSymbol> comparer, AssemblySymbol accessWithinOpt) { Symbol result = null; SymbolKind targetSymbolKind; MethodKind targetMethodKind = MethodKind.Ordinary; bool isStatic = (descriptor.Flags & MemberFlags.Static) != 0; switch (descriptor.Flags & MemberFlags.KindMask) { case MemberFlags.Constructor: targetSymbolKind = SymbolKind.Method; targetMethodKind = MethodKind.Constructor; // static constructors are never called explicitly Debug.Assert(!isStatic); break; case MemberFlags.Method: targetSymbolKind = SymbolKind.Method; break; case MemberFlags.PropertyGet: targetSymbolKind = SymbolKind.Method; targetMethodKind = MethodKind.PropertyGet; break; case MemberFlags.Field: targetSymbolKind = SymbolKind.Field; break; case MemberFlags.Property: targetSymbolKind = SymbolKind.Property; break; default: throw ExceptionUtilities.UnexpectedValue(descriptor.Flags); } foreach (var member in declaringType.GetMembers(descriptor.Name)) { Debug.Assert(member.Name.Equals(descriptor.Name)); if (member.Kind != targetSymbolKind || member.IsStatic != isStatic || !(member.DeclaredAccessibility == Accessibility.Public || ((object)accessWithinOpt != null && Symbol.IsSymbolAccessible(member, accessWithinOpt)))) { continue; } switch (targetSymbolKind) { case SymbolKind.Method: { MethodSymbol method = (MethodSymbol)member; MethodKind methodKind = method.MethodKind; // Treat user-defined conversions and operators as ordinary methods for the purpose // of matching them here. if (methodKind == MethodKind.Conversion || methodKind == MethodKind.UserDefinedOperator) { methodKind = MethodKind.Ordinary; } if (method.Arity != descriptor.Arity || methodKind != targetMethodKind || ((descriptor.Flags & MemberFlags.Virtual) != 0) != (method.IsVirtual || method.IsOverride || method.IsAbstract)) { continue; } if (!comparer.MatchMethodSignature(method, descriptor.Signature)) { continue; } } break; case SymbolKind.Property: { PropertySymbol property = (PropertySymbol)member; if (((descriptor.Flags & MemberFlags.Virtual) != 0) != (property.IsVirtual || property.IsOverride || property.IsAbstract)) { continue; } if (!comparer.MatchPropertySignature(property, descriptor.Signature)) { continue; } } break; case SymbolKind.Field: if (!comparer.MatchFieldSignature((FieldSymbol)member, descriptor.Signature)) { continue; } break; default: throw ExceptionUtilities.UnexpectedValue(targetSymbolKind); } // ambiguity if ((object)result != null) { result = null; break; } result = member; } return(result); }