コード例 #1
0
        /// <summary>
        /// Returns true if the members of superType are accessible from subType due to inheritance.
        /// </summary>
        public static bool IsAccessibleViaInheritance(
            this NamedTypeSymbol superType,
            NamedTypeSymbol subType,
            ref CompoundUseSiteInfo <AssemblySymbol> useSiteInfo
            )
        {
            // NOTE: we don't use strict inheritance.  Instead we ignore constructed generic types
            // and only consider the unconstructed types.  Ecma-334, 4th edition contained the
            // following text supporting this (although, for instance members) in 10.5.3 Protected
            // access for instance members:
            //    In the context of generics (25.1.6), the rules for accessing protected and
            //    protected internal instance members are augmented by the following:
            //    o  Within a generic class G, access to an inherited protected instance member M
            //       using a primary-expression of the form E.M is permitted if the type of E is a
            //       class type constructed from G or a class type derived from a class type
            //       constructed from G.
            // This text is missing in the current version of the spec, but we believe this is accidental.
            NamedTypeSymbol originalSuperType = superType.OriginalDefinition;

            for (
                NamedTypeSymbol?current = subType;
                (object?)current != null;
                current = current.BaseTypeWithDefinitionUseSiteDiagnostics(ref useSiteInfo)
                )
            {
                if (ReferenceEquals(current.OriginalDefinition, originalSuperType))
                {
                    return(true);
                }
            }

            if (originalSuperType.IsInterface)
            {
                foreach (
                    NamedTypeSymbol current in subType.AllInterfacesWithDefinitionUseSiteDiagnostics(
                        ref useSiteInfo
                        )
                    )
                {
                    if (ReferenceEquals(current.OriginalDefinition, originalSuperType))
                    {
                        return(true);
                    }
                }
            }

            // The method returns true for superType == subType.
            // Two different submission type symbols semantically represent a single type, so we should also return true.
            return(superType.TypeKind == TypeKind.Submission &&
                   subType.TypeKind == TypeKind.Submission);
        }