public int Compare(ConstructorInfo lhs, ConstructorInfo rhs) { if (lhs == rhs) { return(0); } Debug.Assert(lhs.DeclaringType == rhs.DeclaringType, "Can only compare constructors for the same type."); var lhsParameters = lhs.GetParameters(); var rhsParameters = rhs.GetParameters(); var lhsUnresolvableParameters = lhsParameters.Where(p => !_engine.CanResolveParameterValue(p, _resolver)).ToArray(); var rhsUnresolvableParameters = rhsParameters.Where(p => !_engine.CanResolveParameterValue(p, _resolver)).ToArray(); var lhsResolvableParameterCount = lhsParameters.Length - lhsUnresolvableParameters.Length; var rhsResolvableParameterCount = rhsParameters.Length - rhsUnresolvableParameters.Length; var lhsUnresolvableParameterWithDefaultValueCount = lhsUnresolvableParameters.Count(p => p.HasDefaultValue); var rhsUnresolvableParameterWithDefaultValueCount = rhsUnresolvableParameters.Count(p => p.HasDefaultValue); var lhsUnresolvableParameterWithoutDefaultValueCount = lhsUnresolvableParameters.Length - lhsUnresolvableParameterWithDefaultValueCount; var rhsUnresolvableParameterWithoutDefaultValueCount = rhsUnresolvableParameters.Length - rhsUnresolvableParameterWithDefaultValueCount; if (lhsUnresolvableParameterWithoutDefaultValueCount < rhsUnresolvableParameterWithoutDefaultValueCount) { return(-1); } if (lhsUnresolvableParameterWithoutDefaultValueCount > rhsUnresolvableParameterWithoutDefaultValueCount) { return(1); } if (lhsResolvableParameterCount > rhsResolvableParameterCount) { return(-1); } if (lhsResolvableParameterCount < rhsResolvableParameterCount) { return(1); } var commonParameterNames = lhsParameters.Where(lp => rhsParameters.Any(rp => lp.Name == rp.Name)).Select(p => p.Name).OrderBy(n => n).ToArray(); var lhsCommonParameters = commonParameterNames.Select(n => lhsParameters.Single(p => p.Name == n)).ToArray(); var rhsCommonParameters = commonParameterNames.Select(n => rhsParameters.Single(p => p.Name == n)).ToArray(); var score = 0; for (int i = 0; i < commonParameterNames.Length; i++) { var lhsParameterType = Nullable.GetUnderlyingType(lhsCommonParameters[i].ParameterType) ?? lhsCommonParameters[i].ParameterType; var rhsParameterType = Nullable.GetUnderlyingType(rhsCommonParameters[i].ParameterType) ?? rhsCommonParameters[i].ParameterType; if (lhsParameterType == rhsParameterType) { continue; } if (rhsParameterType.IsLessSpecificThan(lhsParameterType)) { score--; } if (lhsParameterType.IsLessSpecificThan(rhsParameterType)) { score++; } } if (score < 0) { return(-1); } if (score > 0) { return(1); } if (lhsUnresolvableParameterWithDefaultValueCount < rhsUnresolvableParameterWithDefaultValueCount) { return(-1); } if (lhsUnresolvableParameterWithDefaultValueCount > rhsUnresolvableParameterWithDefaultValueCount) { return(1); } //if (lhs.GetConstructorChain().Contains(rhs)) //{ // return -1; //} //if (rhs.GetConstructorChain().Contains(lhs)) //{ // return 1; //} return(0); }