public SpecializedMethod(IMethod methodDefinition, TypeParameterSubstitution substitution) : base(methodDefinition) { if (substitution == null) { throw new ArgumentNullException("substitution"); } this.methodDefinition = methodDefinition; this.isParameterized = substitution.MethodTypeArguments != null; if (methodDefinition.TypeParameters.Count > 0) { // The method is generic, so we need to specialize the type parameters // (for specializing the constraints, and also to set the correct Owner) specializedTypeParameters = new ITypeParameter[methodDefinition.TypeParameters.Count]; for (int i = 0; i < specializedTypeParameters.Length; i++) { specializedTypeParameters[i] = new SpecializedTypeParameter(methodDefinition.TypeParameters[i], this); } if (!isParameterized) { // Add substitution that replaces the base method's type parameters with our specialized version // but do this only if the type parameters on the baseMember have not already been substituted substitutionWithoutSpecializedTypeParameters = this.Substitution; AddSubstitution(new TypeParameterSubstitution(null, specializedTypeParameters)); } } // Add the main substitution after the method type parameter specialization. AddSubstitution(substitution); if (substitutionWithoutSpecializedTypeParameters != null) { // If we already have a substitution without specialized type parameters, update that: substitutionWithoutSpecializedTypeParameters = TypeParameterSubstitution.Compose(substitution, substitutionWithoutSpecializedTypeParameters); } else { // Otherwise just use the whole substitution, as that doesn't contain specialized type parameters // in this case. substitutionWithoutSpecializedTypeParameters = this.Substitution; } if (specializedTypeParameters != null) { // Set the substitution on the type parameters to the final composed substitution foreach (var tp in specializedTypeParameters.OfType <SpecializedTypeParameter>()) { if (tp.Owner == this) { tp.substitution = base.Substitution; } } } }
/// <summary> /// Performs a substitution. This method may only be called by constructors in derived classes. /// </summary> protected void AddSubstitution(TypeParameterSubstitution newSubstitution) { Debug.Assert(declaringType == null); Debug.Assert(returnType == null); this.substitution = TypeParameterSubstitution.Compose(newSubstitution, this.substitution); }
public virtual IMember Specialize(TypeParameterSubstitution newSubstitution) { return(baseMember.Specialize(TypeParameterSubstitution.Compose(newSubstitution, this.substitution))); }
IMethod IMethod.Specialize(TypeParameterSubstitution newSubstitution) { return(methodDefinition.Specialize(TypeParameterSubstitution.Compose(newSubstitution, substitutionWithoutSpecializedTypeParameters))); }