public ConfigFieldList(object parent) { Parent = parent; configFields.Clear(); foreach (var field in parent.GetType().GetFields()) { object[] attributes = field.GetCustomAttributes(true); var configField = attributes.OfType <ConfigField>().FirstOrDefault(); if (configField.IsNull()) { continue; } if (attributes.OfType <KSPField>().Any()) { throw new NotSupportedException("The property ConfigField is not allowed on a field that also has the KSPField property"); } var isList = field.FieldType.IsListType(); var elementType = isList ? field.FieldType.GetGenericArguments()[0] : field.FieldType; var isIConfigNode = elementType.DerivesFrom(typeof(IConfigNode)); var isParsable = elementType.IsConfigParsableType(); ConfigFieldInfo fieldInfo; if (isList && isParsable) { fieldInfo = new ValueListConfigFieldInfo(parent, field, configField); } else if (isList && isIConfigNode) { fieldInfo = new NodeListConfigFieldInfo(parent, field, configField); } else if (isParsable) { fieldInfo = new ValueScalarConfigFieldInfo(parent, field, configField); } else if (isIConfigNode) { fieldInfo = new NodeScalarConfigFieldInfo(parent, field, configField); } else { throw new NotImplementedException("Cannot find a suitable way to make the field '" + field.Name + "' on the type " + parent.GetType().Name + " into a ConfigField"); } if (configFields.Any(f => f.ConfigName == fieldInfo.ConfigName)) { throw new NotSupportedException("Two ConfigField properties in the same class cannot have the same config name ('" + fieldInfo.ConfigName + "')"); } configFields.Add(fieldInfo); } }