internal static bool ValidateConstraints(ITypeParameter typeParameter, IType typeArgument, TypeVisitor substitution, CSharpConversions conversions) { switch (typeArgument.Kind) // void, null, and pointers cannot be used as type arguments { case TypeKind.Void: case TypeKind.Null: case TypeKind.Pointer: return(false); } if (typeParameter.HasReferenceTypeConstraint) { if (typeArgument.IsReferenceType != true) { return(false); } } if (typeParameter.HasValueTypeConstraint) { if (!NullableType.IsNonNullableValueType(typeArgument)) { return(false); } } if (typeParameter.HasDefaultConstructorConstraint) { ITypeDefinition def = typeArgument.GetDefinition(); if (def != null && def.IsAbstract) { return(false); } var ctors = typeArgument.GetConstructors( m => m.Parameters.Count == 0 && m.Accessibility == Accessibility.Public, GetMemberOptions.IgnoreInheritedMembers | GetMemberOptions.ReturnMemberDefinitions ); if (!ctors.Any()) { return(false); } } foreach (IType constraintType in typeParameter.DirectBaseTypes) { IType c = constraintType; if (substitution != null) { c = c.AcceptVisitor(substitution); } if (!conversions.IsConstraintConvertible(typeArgument, c)) { return(false); } } return(true); }
internal static bool ValidateConstraints(ITypeParameter typeParameter, IType typeArgument, TypeVisitor substitution, CSharpConversions conversions) { switch (typeArgument.Kind) { // void, null, and pointers cannot be used as type arguments case TypeKind.Void: case TypeKind.Null: case TypeKind.Pointer: return false; } if (typeParameter.HasReferenceTypeConstraint) { if (typeArgument.IsReferenceType != true) return false; } if (typeParameter.HasValueTypeConstraint) { if (!NullableType.IsNonNullableValueType(typeArgument)) return false; } if (typeParameter.HasDefaultConstructorConstraint) { ITypeDefinition def = typeArgument.GetDefinition(); if (def != null && def.IsAbstract) return false; var ctors = typeArgument.GetConstructors( m => m.Parameters.Count == 0 && m.Accessibility == Accessibility.Public, GetMemberOptions.IgnoreInheritedMembers | GetMemberOptions.ReturnMemberDefinitions ); if (!ctors.Any()) return false; } foreach (IType constraintType in typeParameter.DirectBaseTypes) { IType c = constraintType; if (substitution != null) c = c.AcceptVisitor(substitution); if (!conversions.IsConstraintConvertible(typeArgument, c)) return false; } return true; }