如何将ICollection<T>序列化为<T>XML的列表?



我正在尝试将List动态序列化为Xml。我可以这样做,只要我没有作为T.属性的ICollection

在将ICollection类型写入Xml之前,我希望将其动态覆盖到List中。

这就是我到目前为止所拥有的。

List<-XmlElementAttribute-> attrToConvertList = new List<-XmlElementAttribute->();
foreach (var propertyInfo in typeof(T).GetProperties())
{
    if (propertyInfo.PropertyType.Name == "ICollection`1")
    {
        XmlElementAttribute attrToConvert = new XmlElementAttribute();
        attrToConvert.ElementName = propertyInfo.Name;
        attrToConvert.Type = typeof(List<>);
        attrToConvert.Type = attrToConvert.Type.MakeGenericType(propertyInfo.PropertyType.GetGenericArguments()[0]);
        attrToConvertList.Add(attrToConvert);
    }
}
XmlAttributeOverrides overrides = new XmlAttributeOverrides();
XmlAttributes attributesToConvert = new XmlAttributes();
foreach (var xmlElementAttribute in attrToConvertList)
    attributesToConvert.XmlElements.Add(xmlElementAttribute);
overrides.Add(typeof(T), attributesToConvert);
XmlSerializer serializer = new XmlSerializer(typeof(List<T>), overrides);

我得到一个错误,我无法序列化类型ICollection,因为它是一个接口。我的印象是,我使用XmlAttributeOverrides所做的操作应该将ICollection覆盖为List类型。

XML序列化不处理接口,显然XmlAttributeOverride不允许您绕过该行为。如果属性是List<T>,则可以更改属性的类型,或生成仅用于序列化的类型。

示例:

class RealClass
{
    ICollection<int> SomeInts { get; set; }
}
class MySerializationClass
{
    private readonly RealClass _wrappedObject;
    public SerializationClass() : this(new RealClass()) { }
    public SerializationClass(RealClass wrappedObject)
    {
        _wrappedObject = wrappedObject;
    }
    public List<T> SomeInts
    {
        get { return new List<T>(_wrappedObject.SomeInts); }
        set { _wrappedObject.SomeInts = value; }
    }
}

您也可以通过显式接口成员实现来实现这一点,并在大多数代码中使用该接口:

interface IHaveSomeInts
{
    ICollection<int> SomeInts { get; set; }
}
class TheClass : IHaveSomeInts
{
    public List<T> SomeInts { get; set; }
    ICollection<T> IHaveSomeInts.SomeInts
    {
        get { return SomeInts; }
        set { SomeInts = new List<T>(value); }
    }
}

当将ICollection<T>分配给IList<T>时,我可能会使用as来查看是否可以只强制转换对象而不是创建新对象,以避免不必要地创建列表。

我通过使用Newton.Json序列化对象解决了最初的问题。

最新更新