一般都需要提供一个通过数字索引的索引器。通过一个元素的关键字索引的索引器也是非常方便的。在这个例子中,关键字是一个字符串名称。两个重写方法CreateNewElement和GetElementKey,对于确保你的集合功能正常非常重要。CreateNewElement有两个重载的方法,一个没有参数,另一个以一个元素名作参数,如果你重载了默认的AddRemoveClearMap行为。更多的关于这个将在高级主题那节讨论。默认,CreateNewElement(string elementName)重载调用CreateNewElement(),所以他并非总是需要重载的。GetElementKey返回指定的配置元素的值,而且返回值唯一标识他。在我们的例子中,关键字是Name属性(property),将在我们的ThingElement定义。最后,你可能已经注意到属性(Properties)集合被重写了。这个原因不是很明显,除非你深入研究.NET框架的源代码,但是可以说这是一个性能优化。
我们的集合并没有完全完成,我们需要收集一些东西。对于我们的例子,就是ThingElement。这是另外一个ConfigurationElement类,类似于我们的之前的NestedElement。
public class ThingElement: ConfigurationElement
{
#region Constructors
/// <summary>
/// Predefines the valid properties and prepares
/// the property collection.
/// </summary>
static ThingElement()
{
// Predefine properties here
s_propName = new ConfigurationProperty(
"name",
typeof(string),
null,
ConfigurationPropertyOptions.IsRequired
);
s_propType = new ConfigurationProperty(
"type",
typeof(string),
"Normal",
ConfigurationPropertyOptions.None
);
s_propColor = new ConfigurationProperty(
"color",
typeof(string),
"Green",
ConfigurationPropertyOptions.None
);
s_properties = new ConfigurationPropertyCollection();
s_properties.Add(s_propName);
s_properties.Add(s_propType);
s_properties.Add(s_propColor);
}
#endregion
#region Static Fields
private static ConfigurationProperty s_propName;
private static ConfigurationProperty s_propType;
private static ConfigurationProperty s_propColor;
private static ConfigurationPropertyCollection s_properties;
#endregion
#region Properties
/// <summary>
/// Gets the Name setting.
/// </summary>
[ConfigurationProperty("name", IsRequired=true)]
public string Name
{
get { return (string)base[s_propName]; }
}
/// <summary>
/// Gets the Type setting.
/// </summary>
[ConfigurationProperty("type")]
public string Type
{
get { return (string)base[s_propType]; }
}
/// <summary>
/// Gets the Type setting.
/// </summary>
[ConfigurationProperty("color")]
public string Color
{
get { return (string)base[s_propColor]; }
}
/// <summary>
/// Override the Properties collection and return our custom one.
/// </summary>
protected override ConfigurationPropertyCollection Properties
{
get { return s_properties; }
}
#endregion
}
{
#region Constructors
/// <summary>
/// Predefines the valid properties and prepares
/// the property collection.
/// </summary>
static ThingElement()
{
// Predefine properties here
s_propName = new ConfigurationProperty(
"name",
typeof(string),
null,
ConfigurationPropertyOptions.IsRequired
);
s_propType = new ConfigurationProperty(
"type",
typeof(string),
"Normal",
ConfigurationPropertyOptions.None
);
s_propColor = new ConfigurationProperty(
"color",
typeof(string),
"Green",
ConfigurationPropertyOptions.None
);
s_properties = new ConfigurationPropertyCollection();
s_properties.Add(s_propName);
s_properties.Add(s_propType);
s_properties.Add(s_propColor);
}
#endregion
#region Static Fields
private static ConfigurationProperty s_propName;
private static ConfigurationProperty s_propType;
private static ConfigurationProperty s_propColor;
private static ConfigurationPropertyCollection s_properties;
#endregion
#region Properties
/// <summary>
/// Gets the Name setting.
/// </summary>
[ConfigurationProperty("name", IsRequired=true)]
public string Name
{
get { return (string)base[s_propName]; }
}
/// <summary>
/// Gets the Type setting.
/// </summary>
[ConfigurationProperty("type")]
public string Type
{
get { return (string)base[s_propType]; }
}
/// <summary>
/// Gets the Type setting.
/// </summary>
[ConfigurationProperty("color")]
public string Color
{
get { return (string)base[s_propColor]; }
}
/// <summary>
/// Override the Properties collection and return our custom one.
/// </summary>
protected override ConfigurationPropertyCollection Properties
{
get { return s_properties; }
}
#endregion
}