如何将app.config自定义节解析为List数据结构?附配置与代码示例
Absolutely! You can parse your custom app.config section into a List<T> structure—you just need to adjust your configuration file format and update your ConfigurationSection implementation to use a collection instead of fixed properties. Here's a step-by-step breakdown:
1. Update Your app.config Structure
First, modify your custom section to use repeatable elements (instead of fixed person1/person2 nodes). A clean approach is to wrap person entries in a container node for clarity:
<configuration> <configSections> <section name="myCustomSection" type="YourNamespace.MyCustomConfiguration, YourAssemblyName" /> </configSections> <myCustomSection> <people> <person name="John" age="30" /> <person name="Mike" age="46" /> </people> </myCustomSection> </configuration>
2. Implement the Person Configuration Element
Create a class to represent a single <person> element, inheriting from ConfigurationElement:
public class PersonConfiguration : ConfigurationElement { [ConfigurationProperty("name", IsRequired = true)] public string Name { get => (string)this["name"]; set => this["name"] = value; } [ConfigurationProperty("age", IsRequired = true)] public int Age { get => (int)this["age"]; set => this["age"] = value; } }
3. Create a Configuration Element Collection
Build a collection class to manage multiple PersonConfiguration instances, inheriting from ConfigurationElementCollection:
public class PersonConfigurationCollection : ConfigurationElementCollection { // Create a new empty PersonConfiguration element protected override ConfigurationElement CreateNewElement() { return new PersonConfiguration(); } // Define the unique key for each element (using the Name property here) protected override object GetElementKey(ConfigurationElement element) { return ((PersonConfiguration)element).Name; } // Indexer to access elements by position public PersonConfiguration this[int index] { get => (PersonConfiguration)BaseGet(index); set { if (BaseGet(index) != null) BaseRemoveAt(index); BaseAdd(index, value); } } // Indexer to access elements by name public new PersonConfiguration this[string name] => (PersonConfiguration)BaseGet(name); }
4. Update the Main Custom Configuration Section
Modify your MyCustomConfiguration class to expose the collection instead of fixed properties:
public class MyCustomConfiguration : ConfigurationSection { [ConfigurationProperty("people", IsRequired = true)] public PersonConfigurationCollection People { get => (PersonConfigurationCollection)this["people"]; set => this["people"] = value; } }
5. Parse the Config into a List
Finally, read the configuration section and convert the collection to a List<PersonConfiguration>:
// Retrieve the custom config section var customConfig = (MyCustomConfiguration)ConfigurationManager.GetSection("myCustomSection"); // Convert the collection to a List List<PersonConfiguration> personList = customConfig.People.Cast<PersonConfiguration>().ToList(); // Example usage: iterate over the list foreach (var person in personList) { Console.WriteLine($"Name: {person.Name}, Age: {person.Age}"); }
Alternative: Skip the Container Node
If you prefer not to use the <people> wrapper, you can make your main MyCustomConfiguration class inherit directly from ConfigurationElementCollection (treating the section itself as the collection). Your config would look like this:
<myCustomSection> <person name="John" age="30" /> <person name="Mike" age="46" /> </myCustomSection>
And the main class would be:
public class MyCustomConfiguration : ConfigurationElementCollection { protected override ConfigurationElement CreateNewElement() => new PersonConfiguration(); protected override object GetElementKey(ConfigurationElement element) => ((PersonConfiguration)element).Name; public PersonConfiguration this[int index] { get => (PersonConfiguration)BaseGet(index); set { if (BaseGet(index) != null) BaseRemoveAt(index); BaseAdd(index, value); } } }
Parsing it would then simplify to:
var customConfig = (MyCustomConfiguration)ConfigurationManager.GetSection("myCustomSection"); List<PersonConfiguration> personList = customConfig.Cast<PersonConfiguration>().ToList();
内容的提问来源于stack exchange,提问作者pepeevich

