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); }
private static void InitDefaultPriorities() { var forString = new ValueDrawerPrioritiesForType(typeof(string)); forString.SetPriority(typeof(StringDrawer <>), 1); }