0

List を Xml に動的にシリアル化しようとしています。T のプロパティとして ICollection を持っていない限り、そうすることができます。

Xml に書き込む前に、ICollection 型を 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 型に上書きすることになっているという印象を受けました。

4

2 に答える 2

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

于 2012-09-14T22:39:21.763 に答える
0

Newton.Json を使用してオブジェクトをシリアル化することで、元の問題を解決しました。

于 2013-02-13T20:31:08.193 に答える