我正在尝试将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序列化对象解决了最初的问题。