コード例 #1
0
        public static IEnumerable <XamlMember> GetSortedConstructorArguments(this XamlType type, IList <object> contents = null)
        {
            var constructors = type.UnderlyingType.GetTypeInfo().GetConstructors();

            if (contents != null && contents.Count > 0)
            {
                var context = type.SchemaContext;

                // find constructor that matches content type directly first, then by ones that can be converted by type
                var constructorArguments =
                    FindConstructorArguments(context, constructors, contents, (type1, type2) => type1.UnderlyingType.GetTypeInfo().IsAssignableFrom(type2.UnderlyingType.GetTypeInfo()))
                    ?? FindConstructorArguments(context, constructors, contents, (type1, type2) => type1.CanConvertFrom(type2));

                if (constructorArguments != null)
                {
                    return(constructorArguments);
                }
            }

            // find constructor based on ConstructorArgumentAttribute
            var args = type.GetConstructorArguments();

            foreach (var ci in constructors)
            {
                var pis = ci.GetParameters();
                if (args.Count != pis.Length)
                {
                    continue;
                }
                bool mismatch = false;
                foreach (var pi in pis)
                {
                    mismatch |= args.All(a => a.ConstructorArgumentName() != pi.Name);
                }
                if (mismatch)
                {
                    continue;
                }
                return(args.OrderBy(c => pis.FindParameterWithName(c.ConstructorArgumentName()).Position));
            }

            return(null);
        }
コード例 #2
0
        public static IEnumerable <XamlMember> GetSortedConstructorArguments(this XamlType type, IList <object> contents = null)
        {
            var constructors = type.UnderlyingType.GetTypeInfo().GetConstructors();

            if (contents != null && contents.Count > 0)
            {
                // find constructor based on supplied parameters
                foreach (var constructor in constructors)
                {
                    var parameters = constructor.GetParameters();
                    if (contents.Count > parameters.Length)
                    {
                        continue;
                    }

                    bool mismatch = false;
                    for (int i = 0; i < parameters.Length; i++)
                    {
                        var parameter = parameters[i];
                        if (i >= contents.Count)
                        {
                            // allow parameters with a default value to be omitted
                            mismatch = !parameter.HasDefaultValue();
                            if (mismatch)
                            {
                                break;
                            }
                            continue;
                        }
                        // check if the parameter value can be assigned to the required type
                        var posParameter  = contents[i];
                        var paramXamlType = type.SchemaContext.GetXamlType(parameter.ParameterType);

                        // check if type input type can be converted to the parameter type
                        var inputType = posParameter == null ? XamlLanguage.Null : type.SchemaContext.GetXamlType(posParameter.GetType());
                        mismatch = !paramXamlType.CanConvertFrom(inputType);
                        if (mismatch)
                        {
                            break;
                        }
                    }
                    if (mismatch)
                    {
                        continue;
                    }

                    // matches constructor arguments
                    return(constructor
                           .GetParameters()
                           .Select(p => type.SchemaContext.GetParameter(p)));
                }
            }

            // find constructor based on ConstructorArgumentAttribute
            var args = type.GetConstructorArguments();

            foreach (var ci in constructors)
            {
                var pis = ci.GetParameters();
                if (args.Count != pis.Length)
                {
                    continue;
                }
                bool mismatch = false;
                foreach (var pi in pis)
                {
                    for (int i = 0; i < args.Count; i++)
                    {
                        mismatch |= args.All(a => a.ConstructorArgumentName() != pi.Name);
                    }
                }
                if (mismatch)
                {
                    continue;
                }
                return(args.OrderBy(c => pis.FindParameterWithName(c.ConstructorArgumentName()).Position));
            }

            return(null);
        }