Frage

Ich habe diese Klasse:

using System;
using System.Collections.Generic;
using System.Runtime.Serialization;

namespace Grouping
{
    [Serializable]
    public class Group<T> : HashSet<T>
    {
        public Group(string name)
        {
            this.name = name;
        }

        protected Group(){}

        protected Group(SerializationInfo info, StreamingContext context):base(info,context)
        {
            name = info.GetString("koosnaampje");
        }

        public override void GetObjectData(SerializationInfo info,StreamingContext context)
        {
            base.GetObjectData(info,context);
            info.AddValue("koosnaampje", Name);
        }

        private string name;
        public string Name
        {
            get { return name; }
            private set { name = value; }
        }
    }
}

Wie aus HashSet erbt hat es ISerializable, daher den geschützten Konstruktor und GetObjectData Methode zu implementieren. Früher serialisiert I und deserialisiert diese Klasse erfolgreich mit dem BinaryFormatter.

Weil ich möchte, um die Ausgabe inspizieren können, die durch den Serializer generiert ich zum DataContractSerializer wechseln wollen.

Ich schrieb diesen Test:

[TestMethod]
public void SerializeTest()
{
    var group = new Group<int>("ints"){1,2,3};
    var serializer = new DataContractSerializer(typeof (Group<int>));
    using (var stream=File.OpenWrite("group1.xml"))
    {
        serializer.WriteObject(stream,group);
    }
    using (var stream=File.OpenRead("group1.xml"))
    {
        group = serializer.ReadObject(stream) as Group<int>;
    }
    Assert.IsTrue(group.Contains(1));
    Assert.AreEqual("ints",group.Name);
}

Der Test schlägt fehl, weil die Name-Eigenschaft ist null! (Die ganzen Zahlen sind (de) serialisiert richtig obwohl) Was ist passiert?

EDIT: es hat nichts mit dem Namen dahinter liegenden Feld ist privat zu tun. es öffentlich zu machen hat das gleiche Ergebnis.

War es hilfreich?

Lösung

Das ist nichts mit ISerializable zu tun; DataContractSerializer einfach nicht Verwendung ISerializable (es IXmlSerializable verwenden, aber Sie wollen nicht, das zu tun ...)

Die meisten Serializer, einschließlich XmlSerializer und DataContractSerializer (und Datenbindung, für diese Angelegenheit), treat Sammlungen als verschiedene Entitäten. Es kann ein oder die andere sein, aber nicht beides. Weil es erkennt, dass es sich um eine „Sammlung“ ist, es serialisiert die Inhalte (das heißt, was auch immer in der Menge enthalten ist), nicht die Eigenschaften (Name usw.).

Sie sollten encapsulate eine Sammlung, anstatt inherit es.

Auch; richtig zu verwenden DataContractSerializer, wäre es klug, die [DataMember] / [DataContract] Attribute hinzuzufügen. Zum Beispiel:

[Serializable, DataContract] // probably don't need [Serializable]
public class Group<T>
{
    [DataMember]
    public HashSet<T> Items { get; private set; }

    protected Group()
    {
        Items = new HashSet<T>();
    }
    public Group(string name) : this()
    {
        Name = name;
    }
    [DataMember]
    public string Name {get ;private set;}
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top