public Boolean SupportsType(TypeInfo typeInfo) { if (typeInfo == null) { throw Logger.Fatal.ArgumentNull(nameof(typeInfo)); } return typeInfo.IsNullable(); }
// // Determines if a value of the source type can be assigned to a location of the target type. // It does not handle ICastable, and cannot since we do not have an actual object instance here. // This routine assumes that the source type is boxed, i.e. a value type source is presumed to be // compatible with Object and ValueType and an enum source is additionally compatible with Enum. // private static bool AreTypesAssignable(TypeInfo pSourceType, TypeInfo pTargetType) { // Special case: T can be cast to Nullable<T> (where T is a value type). Call this case out here // since this is only applicable if T is boxed, which is not true for any other callers of // AreTypesAssignableInternal, so no sense making all the other paths pay the cost of the check. if (pTargetType.IsNullable() && pSourceType.IsValueType && !pSourceType.IsNullable()) { Type pNullableType = pTargetType.GetNullableType(); return AreTypesEquivalentInternal(pSourceType, pNullableType.GetTypeInfo()); } return AreTypesAssignableInternal(pSourceType, pTargetType, true, false); }
static bool SatisfiesConstraints(this TypeInfo genericVariable, SigTypeContext typeContextOfConstraintDeclarer, TypeInfo typeArg) { GenericParameterAttributes specialConstraints = genericVariable.GenericParameterAttributes & GenericParameterAttributes.SpecialConstraintMask; if ((specialConstraints & GenericParameterAttributes.NotNullableValueTypeConstraint) != 0) { if (!typeArg.IsValueType) return false; else { // the type argument is a value type, however if it is any kind of Nullable we want to fail // as the constraint accepts any value type except Nullable types (Nullable itself is a value type) if (typeArg.IsNullable()) return false; } } if ((specialConstraints & GenericParameterAttributes.ReferenceTypeConstraint) != 0) { if (typeArg.IsValueType) return false; } if ((specialConstraints & GenericParameterAttributes.DefaultConstructorConstraint) != 0) { if (!typeArg.HasExplicitOrImplicitPublicDefaultConstructor()) return false; } // Now check general subtype constraints foreach (var constraint in genericVariable.GetGenericParameterConstraints()) { TypeInfo typeConstraint = constraint.GetTypeInfo(); TypeInfo instantiatedTypeConstraint = typeConstraint.Instantiate(typeContextOfConstraintDeclarer); // System.Object constraint will be always satisfied - even if argList is empty if (instantiatedTypeConstraint.IsSystemObject()) continue; // if a concrete type can be cast to the constraint, then this constraint will be satisifed if (!AreTypesAssignable(typeArg, instantiatedTypeConstraint)) return false; } return true; }
public Boolean SupportsType(TypeInfo typeInfo) { if (typeInfo == null) { throw Logger.Fatal.ArgumentNull(nameof(typeInfo)); } if (typeInfo.IsNullable()) { return true; } if (GuidTypeInfo.Equals(typeInfo)) { return true; } if (IEnumerableTypeInfo.IsAssignableFrom(typeInfo)) { return true; } return false; }