发现当自定义应用程序配置节中出现树型结构时将引发 “System.StackOverflowException” 类型异常.
程序集: System.Configuration, Version=2.0.0.0
例: 使用NodeElement(从ConfigurationElement派生)实现自定义配置节,
当获取其属性数据时出现"未处理的“System.StackOverflowException”类型的异常出现在 mscorlib.dll 中。".
代码如下:
public
class
NodeElement : ConfigurationElement {
[ConfigurationProperty( " text " , IsRequired = true )]
public string Text {
get { return ( string ) this [ " text " ]; }
}
[ConfigurationProperty( " child " )]
public NodeElement ChildElement {
get {
return (NodeElement) this [ " child " ];
}
}
}
static class Program {
[STAThread]
static void Main() {
NodeElement node = new NodeElement();
object o = node.ChildElement; // 异常将出现在这里
}
}
[ConfigurationProperty( " text " , IsRequired = true )]
public string Text {
get { return ( string ) this [ " text " ]; }
}
[ConfigurationProperty( " child " )]
public NodeElement ChildElement {
get {
return (NodeElement) this [ " child " ];
}
}
}
static class Program {
[STAThread]
static void Main() {
NodeElement node = new NodeElement();
object o = node.ChildElement; // 异常将出现在这里
}
}
使用 .NET Reflector 查看 System.Configuration.ConfigurationElement 源代码后发现,
当创建 ConfigurationProperty时缺少对属性类型与其当前类型的对比判断, 导致无限递归.
代码如下:
private
static
ConfigurationProperty
CreateConfigurationPropertyFromAttributes(PropertyInfo propertyInformation)
{
ConfigurationProperty property = null ;
if (Attribute.GetCustomAttribute(propertyInformation,
{
ConfigurationProperty property = null ;
if (Attribute.GetCustomAttribute(propertyInformation,
typeof
(ConfigurationPropertyAttribute))
is
ConfigurationPropertyAttribute)
{
property = new ConfigurationProperty(propertyInformation);
}
{
property = new ConfigurationProperty(propertyInformation);
}
//问题出现在下面这句判断
//此处缺少对 property.Type 与当前其所属类型的判断
//导致 PropertiesFromType 方法无限递归.
if
((property
!=
null
)
&&
typeof
(ConfigurationElement).IsAssignableFrom(property.Type))
{
ConfigurationPropertyCollection result = null ;
PropertiesFromType(property.Type, out result);
}
return property;
}
{
ConfigurationPropertyCollection result = null ;
PropertiesFromType(property.Type, out result);
}
return property;
}