Beispiel #1
0
        public override bool Equals(object obj)
        {
            if ((object)this == obj)
            {
                return(true);
            }

            SubstitutedMethodSymbol other = obj as SubstitutedMethodSymbol;

            if ((object)other == null)
            {
                return(false);
            }

            if ((object)this.OriginalDefinition != (object)other.OriginalDefinition &&
                this.OriginalDefinition != other.OriginalDefinition)
            {
                return(false);
            }

            // This checks if the methods have the same definition and the type parameters on the containing types have been
            // substituted in the same way.
            if (this.ContainingType != other.ContainingType)
            {
                return(false);
            }

            // If both are declarations, then we don't need to check type arguments
            // If exactly one is a declaration, then they re not equal
            bool selfIsDeclaration  = (object)this == (object)this.ConstructedFrom;
            bool otherIsDeclaration = (object)other == (object)other.ConstructedFrom;

            // PERF: VSadov specifically replaced the short-circuited operators in changeset #24717.
            if (selfIsDeclaration | otherIsDeclaration)
            {
                return(selfIsDeclaration & otherIsDeclaration);
            }

            // This checks if the type parameters on the method itself have been substituted in the same way.
            int arity = this.Arity;

            for (int i = 0; i < arity; i++)
            {
                // TODO: what about annotations
                if (this.TypeArguments[i].TypeSymbol != other.TypeArguments[i].TypeSymbol)
                {
                    return(false);
                }
            }

            return(true);
        }
            static bool wasConstructedForAnnotations(SubstitutedMethodSymbol method)
            {
                var typeArguments  = method.TypeArgumentsWithAnnotations;
                var typeParameters = method.OriginalDefinition.TypeParameters;

                for (int i = 0; i < typeArguments.Length; i++)
                {
                    if (!typeParameters[i].Equals(
                            typeArguments[i].Type,
                            TypeCompareKind.ConsiderEverything))
                    {
                        return(false);
                    }
                }

                return(true);
            }
        internal static MethodSymbol SubstituteMethodSymbolIfNeeded(MethodSymbol methodSymbol, IGenericContext genericContext)
        {
            if (MetadataGenericContext.IsNullOrEmptyOrNoSpecializations(genericContext))
            {
                return methodSymbol;
            }

            var method = new MetadataMethodAdapter(methodSymbol);
            if (!method.IsGenericMethodDefinition && !method.DeclaringType.IsGenericTypeDefinition)
            {
                return methodSymbol;
            }

            var resolvedMethodSymbol = methodSymbol;
            if (method.DeclaringType.IsGenericTypeDefinition)
            {
                var constructedContainingType = SubstituteTypeSymbolIfNeeded(methodSymbol.ContainingType, genericContext);
                var substitutedNamedTypeSymbol = constructedContainingType as SubstitutedNamedTypeSymbol;
                if (substitutedNamedTypeSymbol != null)
                {
                    resolvedMethodSymbol = new SubstitutedMethodSymbol(
                        substitutedNamedTypeSymbol,
                        methodSymbol.ConstructedFrom.OriginalDefinition);
                }
                else
                {
                    var typeDef = (method.DeclaringType as MetadataTypeAdapter).TypeDef;
                    constructedContainingType = SubstituteTypeSymbolIfNeeded(typeDef, genericContext);
                    resolvedMethodSymbol = (constructedContainingType as ArrayTypeSymbol).GetMembers(methodSymbol.Name)[0] as MethodSymbol;
                }
            }

            if (method.IsGenericMethodDefinition || method.IsGenericMethod)
            {
                return ConstructMethodSymbol(resolvedMethodSymbol, methodSymbol.TypeSubstitution, genericContext);
            }

            return resolvedMethodSymbol;
        }