private static void SetArrayType(FieldInfo field, string value, ProgramOptionsAttribute options, Func <Type, string, object> customValueParser)
        {
            var index     = 0;
            var values    = SplitCollectionValues(options, value);
            var arrayType = field.FieldType;
            var array     = (Array)field.GetValue(null);

            if (array != null)
            {
                var oldArray = array;
                array = (Array)Activator.CreateInstance(arrayType, new object[] { oldArray.Length + values.Length });
                Array.Copy(oldArray, array, oldArray.Length);
                index = oldArray.Length;
            }
            else
            {
                array = (Array)Activator.CreateInstance(arrayType, new object[] { values.Length });
            }

            foreach (var v in values)
            {
                array.SetValue(ParseValue(arrayType.GetElementType(), v, customValueParser), index++);
            }

            field.SetValue(null, array);
        }
        private static Action <string> ActionFor(ProgramOptionsAttribute options, FieldInfo field, Func <Type, string, object> customValueParser)
        {
            if (field.FieldType.IsArray && IsFlagsEnum(field.FieldType.GetElementType()))
            {
                throw new NotSupportedException("The parsing of a flags array is not supported.  There would be no way to know which values to combine together into each element in the array");
            }

            if (field.FieldType.IsArray)
            {
                return(v => SetArrayType(field, v, options, customValueParser));
            }

            if (IsListField(field))
            {
                return(v => SetListType(field, v, options, customValueParser));
            }

            if (field.FieldType == typeof(bool))
            {
                return(v => SetBoolType(field, v));
            }

            if (IsFlagsEnum(field.FieldType))
            {
                return(v => SetFlagsEnumType(field, v, options));
            }

            return(v => SetBasicType(field, v, customValueParser));
        }
        private static IEnumerable <string> OptionNamesFor(ProgramOptionsAttribute options, FieldInfo field)
        {
            var name = NormalizeName(field.Name);

            if (field.FieldType != typeof(bool))
            {
                name += "=";
            }

            if (options.Group == null)
            {
                yield return(name);

                yield return(NormalizeName(field.DeclaringType.Name) + "." + name);
            }
            else
            {
                yield return(options.Group + "." + name);
            }

            foreach (var aliasAttr in field.GetCustomAttributes(typeof(OptionAliasAttribute), false))
            {
                if (field.FieldType != typeof(bool))
                {
                    yield return($"{((OptionAliasAttribute)aliasAttr).Name}=");
                }
                else
                {
                    yield return(((OptionAliasAttribute)aliasAttr).Name);
                }
            }
        }
        private static void SetFlagsEnumType(FieldInfo field, string value, ProgramOptionsAttribute options)
        {
            int finalValue =
                SplitCollectionValues(options, value)
                .Select(v => (int)ParseEnumValue(field.FieldType, v))
                .Aggregate(0, (accum, current) => accum | current);

            field.SetValue(null, finalValue);
        }
        private static void SetListType(FieldInfo field, string value, ProgramOptionsAttribute options, Func <Type, string, object> customValueParser)
        {
            var listType = field.FieldType;
            var list     = (IList)field.GetValue(null) ?? (IList)Activator.CreateInstance(listType);

            foreach (var v in SplitCollectionValues(options, value))
            {
                list.Add(ParseValue(listType.GetGenericArguments()[0], v, customValueParser));
            }

            field.SetValue(null, list);
        }
 private static Action <string> ActionFor(ProgramOptionsAttribute options, FieldInfo field)
 {
 private static string[] SplitCollectionValues(ProgramOptionsAttribute options, string value)
 {
     return(value.Split(new[] { options.CollectionSeparator ?? "," }, StringSplitOptions.None));
 }