Example #1
0
        //
        // Filter by name and visibility from the ReflectedType.
        //
        public static QueriedMemberList <M> Create(RuntimeTypeInfo type, string filter, bool ignoreCase, bool immediateTypeOnly)
        {
            RuntimeTypeInfo reflectedType = type;

            MemberPolicies <M> policies = MemberPolicies <M> .Default;

            NameFilter nameFilter;

            if (filter == null)
            {
                nameFilter = null;
            }
            else if (ignoreCase)
            {
                nameFilter = new NameFilterCaseInsensitive(filter);
            }
            else
            {
                nameFilter = new NameFilterCaseSensitive(filter);
            }

            bool inBaseClass = false;
            QueriedMemberList <M> queriedMembers = new QueriedMemberList <M>(immediateTypeOnly);

            while (type != null)
            {
                int numCandidatesInDerivedTypes = queriedMembers._totalCount;

                foreach (M member in policies.CoreGetDeclaredMembers(type, nameFilter, reflectedType))
                {
                    policies.GetMemberAttributes(member, out MethodAttributes visibility, out bool isStatic, out bool isVirtual, out bool isNewSlot);

                    if (inBaseClass && visibility == MethodAttributes.Private)
                    {
                        continue;
                    }

                    if (numCandidatesInDerivedTypes != 0 && policies.IsSuppressedByMoreDerivedMember(member, queriedMembers._members, startIndex: 0, endIndex: numCandidatesInDerivedTypes))
                    {
                        continue;
                    }

                    BindingFlags allFlagsThatMustMatch = default;
                    allFlagsThatMustMatch |= (isStatic ? BindingFlags.Static : BindingFlags.Instance);
                    if (isStatic && inBaseClass)
                    {
                        allFlagsThatMustMatch |= BindingFlags.FlattenHierarchy;
                    }
                    allFlagsThatMustMatch |= ((visibility == MethodAttributes.Public) ? BindingFlags.Public : BindingFlags.NonPublic);

                    queriedMembers.Add(member, allFlagsThatMustMatch);
                }

                if (!inBaseClass)
                {
                    queriedMembers._declaredOnlyCount = queriedMembers._totalCount;

                    if (immediateTypeOnly)
                    {
                        break;
                    }

                    if (policies.AlwaysTreatAsDeclaredOnly)
                    {
                        break;
                    }
                    inBaseClass = true;
                }

                type = type.BaseType.CastToRuntimeTypeInfo();
                if (type != null && !type.CanBrowseWithoutMissingMetadataExceptions())
                {
                    // If we got here, one of the base classes is missing metadata. We don't want to throw a MissingMetadataException now because we may be
                    // building a cached result for a caller who passed BindingFlags.DeclaredOnly. So we'll mark the results in a way that
                    // it will throw a MissingMetadataException if a caller attempts to iterate past the declared-only subset.
                    queriedMembers._typeThatBlockedBrowsing = type;
                    queriedMembers._totalCount = queriedMembers._declaredOnlyCount;
                    break;
                }
            }

            return(queriedMembers);
        }
Example #2
0
        //
        // Filter by name and visibility from the ReflectedType.
        //
        public static QueriedMemberList <M> Create(RuntimeTypeInfo type, string optionalNameFilter, bool ignoreCase)
        {
            RuntimeTypeInfo reflectedType = type;

            MemberPolicies <M> policies = MemberPolicies <M> .Default;

            NameFilter?nameFilter;

            if (optionalNameFilter == null)
            {
                nameFilter = null;
            }
            else if (ignoreCase)
            {
                nameFilter = new NameFilterCaseInsensitive(optionalNameFilter);
            }
            else
            {
                nameFilter = new NameFilterCaseSensitive(optionalNameFilter);
            }

            bool inBaseClass = false;
            QueriedMemberList <M> queriedMembers = new QueriedMemberList <M>();

            while (type != null)
            {
                int numCandidatesInDerivedTypes = queriedMembers._totalCount;

                foreach (M member in policies.CoreGetDeclaredMembers(type, nameFilter, reflectedType))
                {
                    MethodAttributes visibility;
                    bool             isStatic;
                    bool             isVirtual;
                    bool             isNewSlot;
                    policies.GetMemberAttributes(member, out visibility, out isStatic, out isVirtual, out isNewSlot);

                    if (inBaseClass && visibility == MethodAttributes.Private)
                    {
                        continue;
                    }

                    if (numCandidatesInDerivedTypes != 0 && policies.IsSuppressedByMoreDerivedMember(member, queriedMembers._members, startIndex: 0, endIndex: numCandidatesInDerivedTypes))
                    {
                        continue;
                    }

                    BindingFlags allFlagsThatMustMatch = default(BindingFlags);
                    allFlagsThatMustMatch |= (isStatic ? BindingFlags.Static : BindingFlags.Instance);
                    if (isStatic && inBaseClass)
                    {
                        allFlagsThatMustMatch |= BindingFlags.FlattenHierarchy;
                    }
                    allFlagsThatMustMatch |= ((visibility == MethodAttributes.Public) ? BindingFlags.Public : BindingFlags.NonPublic);

                    queriedMembers.Add(member, allFlagsThatMustMatch);
                }

                if (!inBaseClass)
                {
                    queriedMembers._declaredOnlyCount = queriedMembers._totalCount;
                    if (policies.AlwaysTreatAsDeclaredOnly)
                    {
                        break;
                    }
                    inBaseClass = true;
                }

                type = type.BaseType.CastToRuntimeTypeInfo();
            }

            return(queriedMembers);
        }