// Left unsealed as RuntimeCLSIDTypeInfo has special behavior and needs to override. public override bool HasSameMetadataDefinitionAs(MemberInfo other) { if (other == null) { throw new ArgumentNullException(nameof(other)); } // Do not rewrite as a call to IsConstructedGenericType - we haven't yet established that "other" is a runtime-implemented member yet! RuntimeConstructedGenericTypeInfo otherConstructedGenericType = other as RuntimeConstructedGenericTypeInfo; if (otherConstructedGenericType != null) { other = otherConstructedGenericType.GetGenericTypeDefinition(); } // Unlike most other MemberInfo objects, types never get cloned due to containing generic types being instantiated. // That is, their DeclaringType is always the generic type definition. As a Type, the ReflectedType property is always equal to the DeclaringType. // // Because of these conditions, we can safely implement both the method token equivalence and the "is this type from the same implementor" // check as our regular Equals() method. return(Equals(other)); }
private static RuntimeConstructedGenericTypeInfo WithVerifiedTypeHandle(this RuntimeConstructedGenericTypeInfo genericType, RuntimeTypeInfo[] genericTypeArguments) { // We only permit creating parameterized types if the pay-for-play policy specifically allows them *or* if the result // type would be an open type. RuntimeTypeHandle typeHandle = genericType.InternalTypeHandleIfAvailable; if (IsTypeConstructionEagerlyValidated && typeHandle.IsNull()) { bool atLeastOneOpenType = false; foreach (RuntimeTypeInfo genericTypeArgument in genericTypeArguments) { if (genericTypeArgument.ContainsGenericParameters) { atLeastOneOpenType = true; } } if (!atLeastOneOpenType) { throw ReflectionCoreExecution.ExecutionDomain.CreateMissingConstructedGenericTypeException(genericType.GetGenericTypeDefinition(), genericTypeArguments.CloneTypeArray()); } } return(genericType); }