Ejemplo n.º 1
0
        public static IEnumerable <XamlWriterInternalBase.MemberAndValue> GetSortedConstructorArguments(this XamlType type, IList <XamlWriterInternalBase.MemberAndValue> members)
        {
            var             constructors            = type.UnderlyingType.GetTypeInfo().GetConstructors();
            var             preferredParameterCount = 0;
            ConstructorInfo preferredConstructor    = null;

            foreach (var constructor in constructors)
            {
                var  parameters            = constructor.GetParameters();
                var  matchedParameterCount = 0;
                bool mismatch = false;
                for (int i = 0; i < parameters.Length; i++)
                {
                    var parameter = parameters[i];
                    var member    = members.FirstOrDefault(r => r.Member.ConstructorArgumentName() == parameter.Name);
                    if (member == null)
                    {
                        // allow parameters with a default value to be omitted
                        mismatch = !parameter.HasDefaultValue();
                        if (mismatch)
                        {
                            break;
                        }
                        continue;
                    }
                    var paramXamlType = type.SchemaContext.GetXamlType(parameter.ParameterType);

                    // check if type input type can be converted to the parameter type
                    mismatch = !paramXamlType.CanConvertFrom(member.Member.Type);
                    if (mismatch)
                    {
                        break;
                    }
                    matchedParameterCount++;
                }
                // prefer the constructor that accepts the most parameters
                if (!mismatch && matchedParameterCount > preferredParameterCount)
                {
                    preferredConstructor    = constructor;
                    preferredParameterCount = matchedParameterCount;
                }
            }
            if (preferredConstructor == null)
            {
                return(null);
            }
            return(preferredConstructor
                   .GetParameters()
                   .Select(p => {
                var mem = members.FirstOrDefault(r => r.Member.ConstructorArgumentName() == p.Name);
                if (mem == null && p.HasDefaultValue())
                {
                    mem = new XamlWriterInternalBase.MemberAndValue(type.SchemaContext.GetParameter(p));
                    mem.Value = p.DefaultValue;
                }
                return mem;
            }));
        }