3

BindingList から継承するカスタム タイプのコレクション プロパティがあります。現在、このプロパティは、Setter がなくても XmlSerializer を介してシリアル化されます。現在、このカスタム コレクション クラスに IXmlSerializable を実装しようとしており、コレクション プロパティに Setter がある場合にのみ、WriteXml() および ReadXml() インターフェイス メソッドが呼び出されることを確認しています。Setter がなくても正しくシリアル化される前に、Setter がない限り、シリアル化がこのプロパティを無視するのはなぜですか。

再現するには:

まず、「Item」というクラスを用意します。

public class Item
{
    public Item() {}

    // Generates some random data for the collection
    private MyCollectionType GenerateContent()
    {
        Random ranGen = new Random();
        MyCollectionType collection = new MyCollectionType();

        for (int i = 0; i < 5; i ++)
        {
            collection.Add("Item" + ranGen.Next(0,101));
        }

        return collection;
    }

    public MyCollectionType Items
    {
        get
        {
            if (m_Items == null)
            {
                m_Items = GenerateContent();
            }
            return m_Items;
        }
    }
    private MyCollectionType m_Items = null;
}

次に、コレクション クラス "MyCollectionType" を作成します (最初のスニペットでは IXmlSerializable が意図的に欠落していることに注意してください)。

public class MyCollectionType : BindingList<string>
{
    public MyCollectionType()
    {
        this.ListChanged += MyCollectionType_ListChanged;
    }

    void MyCollectionType_ListChanged(object sender, ListChangedEventArgs e){ }

    public MyCollectionType(ICollection<string> p)
    {
        this.ListChanged  += MyCollectionType_ListChanged;
    }

    #region Implementation of IXmlSerializable

    public void WriteXml(XmlWriter writer)
    {
        throw new NotImplementedException();
    }

    public void ReadXml(XmlReader reader)
    {
        throw new NotImplementedException();
    }

    public XmlSchema GetSchema() { return null; }

    #endregion
}

最後に、「アイテム」をシリアライズおよびデシリアライズするコードを Main() に追加します。

        Item myItem = new Item();
        Item newItem = null;

        // Define an XmlSerializer
        XmlSerializer ser = new XmlSerializer(typeof(Item));

        // Serialize the Object
        using (TextWriter writer = File.CreateText(@"c:\temporary\exportedfromtest.xml"))
        {
            ser.Serialize(writer,myItem);
        }

        // Deserialize it
        using (Stream reader = new FileStream(@"c:\temporary\exportedfromtest.xml", FileMode.Open, FileAccess.Read, FileShare.Read))
        {
            using (XmlDictionaryReader xmlDictionaryReader = XmlDictionaryReader.CreateTextReader(reader, XmlDictionaryReaderQuotas.Max))
            {
                newItem = (Item)ser.Deserialize(xmlDictionaryReader);
            }
        }

したがって、そのまま実行すると、Setter なしでシリアル化および逆シリアル化されることがわかります。現在、コレクションは上記のスニペットに「IXmlSerializable」をリストしていませんが、メソッドはそこにあります。したがって、戻って MyCollectionType クラスに "IXmlSerializable" を追加して再度実行すると、コレクション プロパティがシリアル化されておらず、WriteXml() メソッドと ReadXml() メソッドが呼び出されていないことがわかります。また、空の Setter を追加すると、これらのメソッドが突然呼び出されることに注意してください。

4

1 に答える 1