C# .NET Framework 4.8 XML反序列化派生类失败求助
解决XML反序列化抽象基类派生类的问题
你的核心问题是XmlSerializer没法自动根据<condition>节点的子节点结构判断该实例化哪个派生类,只加[XmlInclude]或者传额外类型数组不够,得给序列化器明确的类型映射规则。下面是具体的解决步骤和代码示例:
1. 调整类的特性配置
保留基类的abstract修饰符,通过**[XmlChoiceIdentifier]**结合枚举来告诉序列化器如何区分派生类:
定义类型枚举
先定义一个枚举,用来标识不同的Condition类型:
public enum ConditionType { ConditionComparison, ConditionTime }
抽象基类Condition
给基类添加[XmlInclude],同时用[XmlChoiceIdentifier]指定类型选择属性,还要定义一个用来标识类型的属性(注意这个属性要标记为[XmlIgnore],避免序列化到XML里):
[XmlInclude(typeof(ConditionComparison))] [XmlInclude(typeof(ConditionTime))] [XmlChoiceIdentifier("ConditionType")] public abstract class Condition { [XmlIgnore] public ConditionType ConditionType { get; set; } }
派生类ConditionComparison
对应包含<channelname>和<value>的节点,添加[XmlType]指定类型名,同时标记对应的属性:
[XmlType("ConditionComparison")] public class ConditionComparison : Condition { public string channelname { get; set; } public string value { get; set; } public ConditionComparison() { ConditionType = ConditionType.ConditionComparison; } }
派生类ConditionTime
对应包含<delay_ms>的节点,同样配置:
[XmlType("ConditionTime")] public class ConditionTime : Condition { public int delay_ms { get; set; } public ConditionTime() { ConditionType = ConditionType.ConditionTime; } }
2. 包含Condition的父类示例
假设你的XML根节点包含<condition>,比如一个Rule类:
public class Rule { public Condition Condition { get; set; } }
3. 反序列化代码
反序列化时,XmlSerializer会根据<condition>的子节点自动匹配对应的派生类:
var xml = @"<Rule> <Condition> <channelname>Channel1</channelname> <value>100</value> </Condition> </Rule>"; var serializer = new XmlSerializer(typeof(Rule)); using (var reader = new StringReader(xml)) { var rule = (Rule)serializer.Deserialize(reader); // rule.Condition 会是 ConditionComparison 实例 } var xmlTime = @"<Rule> <Condition> <delay_ms>5000</delay_ms> </Condition> </Rule>"; using (var readerTime = new StringReader(xmlTime)) { var ruleTime = (Rule)serializer.Deserialize(readerTime); // ruleTime.Condition 会是 ConditionTime 实例 }
为什么之前的方法无效?
- 只加
[XmlInclude]时,XmlSerializer不知道如何从同名的<condition>节点里区分派生类,需要额外的类型标识规则 - 移除
abstract后,序列化器会默认实例化基类,因为它没收到明确的派生类映射指令 - 构造XmlSerializer时传额外类型数组,本质和加
[XmlInclude]效果一样,还是缺少类型区分的逻辑
内容的提问来源于stack exchange,提问作者Valentin Weiß
相关产品推荐
相关产品推荐

