2016-09-06 8 views
3

基本的にはいくつかのメタデータとジェネリックリストを持つコンテナであるジェネリック型Foo1を持っています。私はその型をシリアル化すると、 "Foo1Of" + TypeParameterNameという名前を取得します。C#でIEnumerableを実装しているカスタムジェネリック型をシリアライズ

<?xml version="1.0" encoding="utf-16"?> 
<Foo1OfString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <Name>Foo1</Name> 
    <List><string>Bar</string><string>Baz</string></List> 
</Foo1OfString> 

は、より直接的に、私は、IEnumerableをIEnumerableを実装し、Add(...)メソッドの内部リストにアクセスするには:

public class Foo1<T> 
{ 
    public string Name { get; set; } = string.Empty; 

    public List<T> List { get; set; } = new List<T>(); 
} 

[TestMethod] 
public void SerializeFoo1() 
{ 
    Foo1<string> foo = new Foo1<string> 
    { 
     Name = "Foo1", 
     List = 
     { 
      "Bar", 
      "Baz" 
     } 
    }; 

    XmlSerializer s = new XmlSerializer(foo.GetType()); 
    StringBuilder sb = new StringBuilder(); 
    XmlWriter w = XmlWriter.Create(sb); 

    s.Serialize(w, foo); 

    Console.WriteLine(sb.ToString()); 
} 

これは古いバージョンとリターンがあります。

public class Foo2<T> : IEnumerable<T>, IEnumerable 
{ 
    public string Name { get; set; } = string.Empty; 

    public List<T> List { get; set; } = new List<T>(); 

    public void Add(T item) 
    { 
     List.Add(item); 
    } 

    public IEnumerator<T> GetEnumerator() 
    { 
     return List.GetEnumerator(); 
    } 

    IEnumerator IEnumerable.GetEnumerator() 
    { 
     return List.GetEnumerator(); 
    } 
} 

[TestMethod] 
public void SerializeFoo2() 
{ 
    Foo2<string> foo = new Foo2<string> 
    { 
     Name = "Foo2", 
     List = 
     { 
      "Bar", 
      "Baz" 
     } 
    }; 

    XmlSerializer s = new XmlSerializer(foo.GetType()); 
    StringBuilder sb = new StringBuilder(); 
    XmlWriter w = XmlWriter.Create(sb); 

    s.Serialize(w, foo); 

    Console.WriteLine(sb.ToString()); 
} 

はそれをやった後、XMLシリアル化は非常に奇妙な振る舞い:

<?xml version="1.0" encoding="utf-16"?> 
<ArrayOfString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <string>Bar</string><string>Baz</string> 
</ArrayOfString> 

名が "ArrayOf" + TypeParameterNameとプロパティ "名前" 消えます。 XmlSerializerは、私のカスタム型が配列だと思うようです。この動作を変更する方法はありますか?つまり、インターフェイスを実装し、追加(...)することはできますが、古いXMLのシリアル化は可能ですか?

答えて

3

IEnumerable<T>インターフェイスを実装しているので、これはXmlSerializerの既定の動作です。 IEnumerable<string>型のため、XmlSerializerはそれが文字列のコレクション/配列だと考えます。

IEnumerable<T>を実装する必要がある場合、このデフォルトの動作を克服する1つの方法は、カスタムシリアル化を実装することです。 Foo1<T>IXmlSerializableを実装します。必要に応じてXmlグラフをカスタマイズし、希望する名前とリストを返すことができます。 XmlSerializerはカスタム実装になります。