如何将ICollection <t>序列化为List <t>到Xml?</t> </t>

时间:2012-09-14 22:10:02

标签: c# reflection xmlserializer

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

我想在将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类型。

2 个答案:

答案 0 :(得分:0)

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来查看是否可以投放对象而不是创建新对象,以避免不必要地创建列表。

答案 1 :(得分:0)

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