| File: System\Reflection\Runtime\BindingFlagSupport\PropertyPolicies.cs | Web Access |
| Project: src\runtime\src\libraries\System.Reflection.MetadataLoadContext\src\System.Reflection.MetadataLoadContext.csproj (System.Reflection.MetadataLoadContext) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; using RuntimeTypeInfo = System.Reflection.TypeLoading.RoType; namespace System.Reflection.Runtime.BindingFlagSupport { /// <summary> /// Policies for properties. /// </summary> internal sealed class PropertyPolicies : MemberPolicies<PropertyInfo> { public sealed override IEnumerable<PropertyInfo> GetDeclaredMembers(TypeInfo typeInfo) { return typeInfo.DeclaredProperties; } public sealed override IEnumerable<PropertyInfo> CoreGetDeclaredMembers(RuntimeTypeInfo type, NameFilter? filter, RuntimeTypeInfo reflectedType) { return type.GetPropertiesCore(filter, reflectedType); } public sealed override bool AlwaysTreatAsDeclaredOnly => false; public sealed override void GetMemberAttributes(PropertyInfo member, out MethodAttributes visibility, out bool isStatic, out bool isVirtual, out bool isNewSlot) { MethodInfo? accessorMethod = GetMostAccessibleAccessor(member); if (accessorMethod == null) { // If we got here, this is a inherited PropertyInfo that only had private accessors and is now refusing to give them out // because that's what the rules of inherited PropertyInfo's are. Such a PropertyInfo is also considered private and will never be // given out of a Type.GetProperty() call. So all we have to do is set its visibility to Private and it will get filtered out. // Other values need to be set to satisfy C# but they are meaningless. visibility = MethodAttributes.Private; isStatic = false; isVirtual = false; isNewSlot = true; return; } MethodAttributes methodAttributes = accessorMethod.Attributes; visibility = methodAttributes & MethodAttributes.MemberAccessMask; isStatic = (0 != (methodAttributes & MethodAttributes.Static)); isVirtual = (0 != (methodAttributes & MethodAttributes.Virtual)); isNewSlot = (0 != (methodAttributes & MethodAttributes.NewSlot)); } public sealed override bool ImplicitlyOverrides(PropertyInfo? baseMember, PropertyInfo? derivedMember) { MethodInfo? baseAccessor = GetAccessorMethod(baseMember!); MethodInfo? derivedAccessor = GetAccessorMethod(derivedMember!); return MemberPolicies<MethodInfo>.Default.ImplicitlyOverrides(baseAccessor, derivedAccessor); } // // .NET Framework compat: Properties hide properties in base types if they share the same vtable slot, or // have the same name, return type, signature and hasThis value. // public sealed override bool IsSuppressedByMoreDerivedMember(PropertyInfo member, PropertyInfo[] priorMembers, int startIndex, int endIndex) { MethodInfo baseAccessor = GetAccessorMethod(member)!; for (int i = startIndex; i < endIndex; i++) { PropertyInfo prior = priorMembers[i]; MethodInfo derivedAccessor = GetAccessorMethod(prior)!; if (!AreNamesAndSignaturesEqual(baseAccessor, derivedAccessor)) continue; if (derivedAccessor.IsStatic != baseAccessor.IsStatic) continue; if (!(prior.PropertyType.Equals(member.PropertyType))) continue; return true; } return false; } public sealed override bool OkToIgnoreAmbiguity(PropertyInfo m1, PropertyInfo m2) { return false; } private static MethodInfo? GetAccessorMethod(PropertyInfo property) => property.GetMethod ?? property.SetMethod; private static MethodInfo? GetMostAccessibleAccessor(PropertyInfo property) { MethodInfo? getter = property.GetMethod; MethodInfo? setter = property.SetMethod; if (getter == null) return setter; if (setter == null) return getter; // Return the setter if it's more accessible, otherwise return the getter. // MethodAttributes acessibility values are higher for more accessible methods: private (1) --> public (6). return (setter.Attributes & MethodAttributes.MemberAccessMask) > (getter.Attributes & MethodAttributes.MemberAccessMask) ? setter : getter; } } }