private static bool VerifyGenericParamConstraint(InstantiationContext genericParamContext, GenericParameterDesc genericParam, InstantiationContext instantiationParamContext, TypeDesc instantiationParam) { GenericConstraints constraints = genericParam.Constraints; // Check class constraint if ((constraints & GenericConstraints.ReferenceTypeConstraint) != 0) { if (!instantiationParam.IsGCPointer && !CheckGenericSpecialConstraint(instantiationParam, GenericConstraints.ReferenceTypeConstraint)) { return(false); } } // Check default constructor constraint if ((constraints & GenericConstraints.DefaultConstructorConstraint) != 0) { if (!instantiationParam.HasExplicitOrImplicitDefaultConstructor() && !CheckGenericSpecialConstraint(instantiationParam, GenericConstraints.DefaultConstructorConstraint)) { return(false); } } // Check struct constraint if ((constraints & GenericConstraints.NotNullableValueTypeConstraint) != 0) { if ((!instantiationParam.IsValueType || instantiationParam.IsNullable) && !CheckGenericSpecialConstraint(instantiationParam, GenericConstraints.NotNullableValueTypeConstraint)) { return(false); } } var instantiatedConstraints = new ArrayBuilder <TypeDesc>(); GetInstantiatedConstraintsRecursive(instantiationParamContext, instantiationParam, ref instantiatedConstraints); foreach (var constraintType in genericParam.TypeConstraints) { var instantiatedType = constraintType.InstantiateSignature(genericParamContext.TypeInstantiation, genericParamContext.MethodInstantiation); if (CanCastConstraint(ref instantiatedConstraints, instantiatedType)) { continue; } if (!instantiationParam.CanCastTo(instantiatedType)) { return(false); } } return(true); }
private static bool VerifyGenericParamConstraint(Instantiation typeInstantiation, Instantiation methodInstantiation, GenericParameterDesc genericParam, TypeDesc instantiationParam) { GenericConstraints constraints = genericParam.Constraints; // Check class constraint if ((constraints & GenericConstraints.ReferenceTypeConstraint) != 0) { if (!instantiationParam.IsGCPointer) { return(false); } } // Check default constructor constraint if ((constraints & GenericConstraints.DefaultConstructorConstraint) != 0) { if (!instantiationParam.HasExplicitOrImplicitDefaultConstructor()) { return(false); } } // Check struct constraint if ((constraints & GenericConstraints.NotNullableValueTypeConstraint) != 0) { if (!instantiationParam.IsValueType) { return(false); } if (instantiationParam.IsNullable) { return(false); } } foreach (var constraintType in genericParam.TypeConstraints) { var instantiatedType = constraintType.InstantiateSignature(typeInstantiation, methodInstantiation); if (!instantiationParam.CanCastTo(instantiatedType)) { return(false); } } return(true); }