private ValueDrawerTypeInfo(Type type) : base(type) { Ensure.Argument.NotNull(type, "type"); Ensure.Argument.Is(type, "type", ValueDrawerTypes.Root); if (Type.IsGenericType) { GenericDefinitionInfo = Type.IsGenericTypeDefinition ? this : Get(Type.GetGenericTypeDefinition()); } var argsForConstraints = GenericDefinitionInfo != null ? GenericDefinitionInfo.GenericArguments : GenericArguments; if (argsForConstraints.Owner.IsGenericParameter) { ConstraintsOnOwner = new GenericParameterConstraints(argsForConstraints.Owner); } if (argsForConstraints.Value.IsGenericParameter) { ConstraintsOnValue = new GenericParameterConstraints(argsForConstraints.Value); } if (ConstraintsOnValue != null) { IsInterfaceDrawer = ConstraintsOnValue.TypeCount > 0 && ConstraintsOnValue.Types.All(t => t.IsInterface); } }
private Type BuildImpl(Type ownerType, Type valueType) { CheckUserArgIfRootIsSpecificType(ownerType, "ownerType", GenericArgOwnerIndex); CheckUserArgIfRootIsSpecificType(valueType, "valueType", GenericArgValueIndex); Type[] specificArgs; if (!TryExtractSpecificGenericArgs(ownerType, valueType, out specificArgs)) { var msg = string.Format( "Unable to extract generic arguments from '{0}' and '{1}' for {2}", ownerType, valueType, DrawerTypeDef); throw new TypeLoadException(msg); } for (int i = 0; i < genericArgs.Count; ++i) { Type sa = specificArgs[i], ga = genericArgs[i]; if (!GenericParameterConstraints.Match(sa, ga)) { throw new ArgumentException(string.Format("Generic argument '{0}' not match with '{1}'.", sa, ga)); } } return(DrawerTypeDef.MakeGenericType(specificArgs)); }
private int CompareImpl(Type l, Type r) { int value; if (!CompareUtil.PreCompare(l, r, out value)) { return(value); } // Use default compare if any argument is not type of ValueDrawer. var root = ValueDrawerTypes.Root; if (!root.IsAssignableFrom(l) || !root.IsAssignableFrom(r)) { return(Comparer <Type> .Default.Compare(l, r)); } var priorities = ValueDrawerPrioritiesForType.Get(ValueType ?? typeof(object)); if (priorities != null) { var lg = l.IsGenericType ? l.GetGenericTypeDefinition() : l; var rg = r.IsGenericType ? r.GetGenericTypeDefinition() : r; int lp = priorities.GetPriority(lg), rp = priorities.GetPriority(rg); return(lp.CompareTo(rp)); } ValueDrawerTypeInfo lInfo = ValueDrawerTypeInfo.Get(l), rInfo = ValueDrawerTypeInfo.Get(r); if (lInfo != null && rInfo != null) { // Interface drawer is more appropriate for interface type. if (lInfo.IsInterfaceDrawer && !rInfo.IsInterfaceDrawer) { return(ValueType.IsInterface ? 1 : -1); } if (!lInfo.IsInterfaceDrawer && rInfo.IsInterfaceDrawer) { return(ValueType.IsInterface ? -1 : 1); } GenericParameterConstraints lcov = lInfo.ConstraintsOnValue, rcov = rInfo.ConstraintsOnValue; if (lcov != null && rcov != null) { if (lcov.TypeCount == 1 && rcov.TypeCount == 1) { Type lIf = rcov.GetType(0), rIf = rcov.GetType(0); if (lIf != rIf) { if (lIf.IsAssignableFrom(rIf)) { return(-1); } if (rIf.IsAssignableFrom(lIf)) { return(1); } } } } // The more the drawer type derived, the higher priority it owned. return(lInfo.DeriveDepth.CompareTo(rInfo.DeriveDepth)); } return(0); }