如何使用接口类型数组 属性 序列化对象?
How to serialize object with interface typed array property?
我有一些 XML,我希望使用 XmlSerializer
进行序列化和反序列化。我希望将来能够使用其他串行格式,例如 JSON、YAML 等,因此我从反序列化中得到的 classes 应该共享相同的接口。
但是,我的接口包含一组也使用接口的对象:
public interface IConfiguration
{
ICommand[] Commands { get; set; }
}
public Interface ICommand
{
// Command properties
}
[System.SerializableAttribute()]
public XmlConfiguration : IConfiguration
{
ICommand[] Commands { get; set; }
}
[System.SerializableAttribute()]
public XmlCommand : ICommand
{
// Command properties
}
XML 反序列化操作如何知道在创建 XmlConfiguration
对象时使用 XmlCommand
具体类型?
一边打字一边思考...
我想我可以向 XmlConfiguration
class 添加一个构造函数来分配一个具体类型的空数组,但我不确定这是否会按预期工作?
[System.SerializableAttribute()]
class XmlConfiguration : IConfiguration
{
public XmlConfiguration()
{
Commands = new XmlCommand[] { };
}
}
更新: 我知道有 XmlArrayItemAttribute
属性可用,但不确定它是否适用于接口:
class XmlConfiguration : IConfiguration
{
[System.Xml.Serialization.XmlArrayItemAttribute(typeof(XmlCommand))]
public ICommand[] Commands { get; set; }
}
更新:我大概也能做到:
class XmlConfiguration : IConfiguration
{
[System.Xml.Serialization.XmlIgnoreAttribute()]
public ICommand[] Command
{
get => CommandsConcrete;
set => CommandsConcrete = (XmlCommand[])value;
}
[System.Xml.Serialization.XmlElementAttribute(ElementName = "Commands")]
public XmlCommand[] CommandsConcrete { get; set; }
}
序列化接口 属性 一个简单的可能性是使用另一个 属性。您仍然需要使用 [XmlInclude]
作为序列化程序来了解可能发生的所有类型:
public interface ICommand
{
string Text { get; set; }
}
public class CommandA : ICommand
{
public string Text { get; set; }
}
public class CommandB : ICommand
{
public string Text { get; set; }
}
[XmlInclude(typeof(CommandA))]
[XmlInclude(typeof(CommandB))]
public class Settings
{
[XmlIgnore]
public ICommand[] Commands { get; set; }
[XmlArray(nameof(Commands))]
public object[] CommandsSerialize
{
get { return Commands; }
set { Commands = value.Cast<ICommand>().ToArray(); }
}
}
序列化后会产生
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Commands>
<anyType xsi:type="CommandA">
<Text>a</Text>
</anyType>
<anyType xsi:type="CommandB">
<Text>b</Text>
</anyType>
</Commands>
</Settings>
我有一些 XML,我希望使用 XmlSerializer
进行序列化和反序列化。我希望将来能够使用其他串行格式,例如 JSON、YAML 等,因此我从反序列化中得到的 classes 应该共享相同的接口。
但是,我的接口包含一组也使用接口的对象:
public interface IConfiguration
{
ICommand[] Commands { get; set; }
}
public Interface ICommand
{
// Command properties
}
[System.SerializableAttribute()]
public XmlConfiguration : IConfiguration
{
ICommand[] Commands { get; set; }
}
[System.SerializableAttribute()]
public XmlCommand : ICommand
{
// Command properties
}
XML 反序列化操作如何知道在创建 XmlConfiguration
对象时使用 XmlCommand
具体类型?
一边打字一边思考...
我想我可以向 XmlConfiguration
class 添加一个构造函数来分配一个具体类型的空数组,但我不确定这是否会按预期工作?
[System.SerializableAttribute()]
class XmlConfiguration : IConfiguration
{
public XmlConfiguration()
{
Commands = new XmlCommand[] { };
}
}
更新: 我知道有 XmlArrayItemAttribute
属性可用,但不确定它是否适用于接口:
class XmlConfiguration : IConfiguration
{
[System.Xml.Serialization.XmlArrayItemAttribute(typeof(XmlCommand))]
public ICommand[] Commands { get; set; }
}
更新:我大概也能做到:
class XmlConfiguration : IConfiguration
{
[System.Xml.Serialization.XmlIgnoreAttribute()]
public ICommand[] Command
{
get => CommandsConcrete;
set => CommandsConcrete = (XmlCommand[])value;
}
[System.Xml.Serialization.XmlElementAttribute(ElementName = "Commands")]
public XmlCommand[] CommandsConcrete { get; set; }
}
序列化接口 属性 一个简单的可能性是使用另一个 属性。您仍然需要使用 [XmlInclude]
作为序列化程序来了解可能发生的所有类型:
public interface ICommand
{
string Text { get; set; }
}
public class CommandA : ICommand
{
public string Text { get; set; }
}
public class CommandB : ICommand
{
public string Text { get; set; }
}
[XmlInclude(typeof(CommandA))]
[XmlInclude(typeof(CommandB))]
public class Settings
{
[XmlIgnore]
public ICommand[] Commands { get; set; }
[XmlArray(nameof(Commands))]
public object[] CommandsSerialize
{
get { return Commands; }
set { Commands = value.Cast<ICommand>().ToArray(); }
}
}
序列化后会产生
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Commands>
<anyType xsi:type="CommandA">
<Text>a</Text>
</anyType>
<anyType xsi:type="CommandB">
<Text>b</Text>
</anyType>
</Commands>
</Settings>