0

我正在尝试将 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 覆盖为类型列表。

4

2 回答 2

0

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

于 2013-02-13T20:31:08.193 回答
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); }
    }
}

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

于 2012-09-14T22:39:21.763 回答