コード例 #1
0
            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);
            }