System.Xml.Serialization 中作为 XmlElementAttribute 参数的元素名称或类型
Element name or type as argument to XmlElementAttribute in System.Xml.Serialization
同时使用XmlSerializer
反序列化
案例一:
Presentation
包含 Slide
类型的子元素
<Presentation>
<Slide>
...
</Slide>
</Presentation>
nameof
获取正确的结果,即 elementName
应该通过。将其替换为 typeof
会给出不正确的结果。
public class Presentation
{
...
[XmlElement(nameof(Slide))]
public List<Slide> Slides { get; set; }
...
}
案例二:
Slide
包含派生自基础 class Shape
的 TextBox
或 Table
类型的子元素
<Slide>
<TextBox>
...
</TextBox>
<Table>
...
</Table>
</Slide>
typeof
获取正确的结果,即 type
应该通过。将其替换为 nameof
会给出不正确的结果。
public class Slide
{
...
[XmlElement(typeof(TextBox))]
[XmlElement(typeof(Table))]
public List<Shape> Shapes { get; set; }
...
}
谁能解释一下上面的内容?什么时候提供元素名称,什么时候提供类型?
基于 C# 属性,XmlSerializer
构造函数通过使用反射分析 类 生成一对 XmlSerializationReader
和 XmlSerializationWriter
派生的 类 [1]. A mapping between the element names in the XML and types in C# is then also established[2].
当XmlElementAttribute(string elementName, Type type)
用于集合时,每个属性对应一个这样的映射。这取决于每个属性的以下逻辑
不指定type时,根据集合中元素的类型推断
如果指定一个属性或不指定属性(相同类型对象的集合)
- 未指定名称时,从属性
的名称推断
如果指定了两个或多个属性(不同类型对象的集合)
- 未指定名称时,根据提供给属性或由属性推断的类型的名称推断
这在 documentation of XmlAttribute
中也有说明
Note that when you apply the XmlElementAttribute multiple times without specifying an ElementName property value, the elements are named after the type of the acceptable objects.
现在参考OP,
案例一:
[XmlElement(nameof(Slide))]
类似于
[XmlElement("Slide", typeof(Slide))]
将其替换为 typeof
将类似于
[XmlElement("Slides", typeof(Slide))]
这意味着我们需要将 "Slides"
指定为 XML 中的元素名称而不是 "Slide"
,因此结果不正确。
案例二:
[XmlElement(typeof(TextBox))]
[XmlElement(typeof(Table))]
类似于
[XmlElement("TextBox", typeof(TextBox))]
[XmlElement("Table", typeof(Table))]
将其替换为 nameof
将类似于
[XmlElement("TextBox", typeof(Shape))]
[XmlElement("Table", typeof(Shape))]
此处,在 TextBox
和 Table
之间,对于类型 Shape
的映射内容存在歧义。因此,映射本身无法建立,代码退出。
同时使用XmlSerializer
反序列化
案例一:
Presentation
包含 Slide
<Presentation>
<Slide>
...
</Slide>
</Presentation>
nameof
获取正确的结果,即 elementName
应该通过。将其替换为 typeof
会给出不正确的结果。
public class Presentation
{
...
[XmlElement(nameof(Slide))]
public List<Slide> Slides { get; set; }
...
}
案例二:
Slide
包含派生自基础 class Shape
TextBox
或 Table
类型的子元素
<Slide>
<TextBox>
...
</TextBox>
<Table>
...
</Table>
</Slide>
typeof
获取正确的结果,即 type
应该通过。将其替换为 nameof
会给出不正确的结果。
public class Slide
{
...
[XmlElement(typeof(TextBox))]
[XmlElement(typeof(Table))]
public List<Shape> Shapes { get; set; }
...
}
谁能解释一下上面的内容?什么时候提供元素名称,什么时候提供类型?
基于 C# 属性,XmlSerializer
构造函数通过使用反射分析 类 生成一对 XmlSerializationReader
和 XmlSerializationWriter
派生的 类 [1]. A mapping between the element names in the XML and types in C# is then also established[2].
当XmlElementAttribute(string elementName, Type type)
用于集合时,每个属性对应一个这样的映射。这取决于每个属性的以下逻辑
不指定type时,根据集合中元素的类型推断
如果指定一个属性或不指定属性(相同类型对象的集合)
- 未指定名称时,从属性 的名称推断
如果指定了两个或多个属性(不同类型对象的集合)
- 未指定名称时,根据提供给属性或由属性推断的类型的名称推断
这在 documentation of XmlAttribute
中也有说明Note that when you apply the XmlElementAttribute multiple times without specifying an ElementName property value, the elements are named after the type of the acceptable objects.
现在参考OP,
案例一:
[XmlElement(nameof(Slide))]
类似于
[XmlElement("Slide", typeof(Slide))]
将其替换为 typeof
将类似于
[XmlElement("Slides", typeof(Slide))]
这意味着我们需要将 "Slides"
指定为 XML 中的元素名称而不是 "Slide"
,因此结果不正确。
案例二:
[XmlElement(typeof(TextBox))]
[XmlElement(typeof(Table))]
类似于
[XmlElement("TextBox", typeof(TextBox))]
[XmlElement("Table", typeof(Table))]
将其替换为 nameof
将类似于
[XmlElement("TextBox", typeof(Shape))]
[XmlElement("Table", typeof(Shape))]
此处,在 TextBox
和 Table
之间,对于类型 Shape
的映射内容存在歧义。因此,映射本身无法建立,代码退出。