Δημιουργήστε δείκτη στο γονικό αντικείμενο στη διαδικασία deserialization σε C #

ψήφοι
4

Έχω κατηγορίες όπως:

[Serializable]
public class child {
     public Parent parent;
}

[Serializable]
public class Parent {
  public List<child> children;
}

Όταν κατάργηση σειράς γονέα, θέλω κάθε ένα από το καθένα τα παιδιά να έχουν μια αναφορά σε αυτό είναι η μητρική. Το ερώτημα είναι, όπου κατά τη διαδικασία deserialization μπορώ να ορίσω του παιδιού «μητρική» pointer; Δεν μπορώ να φαίνεται για να χρησιμοποιήσετε ένα προσαρμοσμένο κατασκευαστή για το παιδί, επειδή deserialization χρησιμοποιεί πάντα την προεπιλεγμένη κατασκευαστή. Αν έχω εφαρμόσει ISerializable, τότε φαίνεται ότι τα αντικείμενα παιδικής έχουν ήδη δημιουργηθεί από τη στιγμή που ο γονέας έχει δημιουργηθεί. Είναι ένας άλλος τρόπος για να επιτευχθεί αυτό;

Δημοσιεύθηκε 09/12/2008 στις 18:20
πηγή χρήστη
Σε άλλες γλώσσες...                            


4 απαντήσεις

ψήφοι
8

Οι κυκλικές αναφορές αντιμετωπίζονται διαφορετικά για την BinaryFormatter, XmlSerializerκαι DataContractSerializer.

Τα BinaryFormatterστηρίγματα κυκλικές αναφορές από προεπιλογή, δεν απαιτείται εργασία:

using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;

[Serializable]
public class Child
{
    public Guid Id { get; set; }

    public Parent parent;
}

[Serializable]
public class Parent
{
    public Guid Id;

    public List<Child> Children;
}

class Program
{
    static void Main(string[] args)
    {
        Child c1 = new Child { Id = Guid.NewGuid() };
        Child c2 = new Child { Id = Guid.NewGuid() };

        Parent p = new Parent { Id = Guid.NewGuid(), Children = new List<Child> { c1, c2 } };

        c1.parent = p;
        c2.parent = p;

        using (var stream1 = new MemoryStream())
        {
            BinaryFormatter formatter = new BinaryFormatter();
            formatter.Serialize(stream1, p);
            stream1.Position = 0;

            var deserializedParent = formatter.Deserialize(stream1) as Parent;
            foreach (var child in deserializedParent.Children)
            {
                Console.WriteLine("Child Id: {0}, Parent Id: {1}", child.Id, child.parent.Id);
            }
        }

        Console.ReadLine();
    }
}

Όταν χρησιμοποιείτε το XmlSerializer, αποφύγετε την κυκλική refernce με το να μην συνέχειες αναφορά του παιδιού στον γονέα και να εξασφαλίσει ότι η σχέση είναι σταθερή κατά τη διάρκεια της διαδικασίας deserialization. Αυτό γίνεται με την εφαρμογή της IXmlSerializableδιεπαφής και το χειρισμό serialization και deserialization.

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Linq;
using System.Xml.Serialization;

namespace XmlSerialization
{

    [Serializable]
    public class Child
    {
        public Guid Id { get; set; }

        [XmlIgnore] // Don't serialize the reference to the parent
        public Parent parent;
    }

    [Serializable]
    public class Parent : IXmlSerializable
    {
        public List<Child> Children;

        public Guid Id;

        public System.Xml.Schema.XmlSchema GetSchema()
        {
            return null;
        }

        public void ReadXml(System.Xml.XmlReader reader)
        {
            XElement xml = XElement.ReadFrom(reader) as XElement;
            if (xml != null)
            {
                // Deserialize Children
                Children = 
                    xml.Descendants("Child")
                       .Select(x => new Child() { Id = Guid.Parse(x.Element("Id").Value), parent = this })
                       .ToList();

                // Deserialize Id
                Id = Guid.Parse(xml.Attribute("Id").Value); 
            }
        }

        public void WriteXml(System.Xml.XmlWriter writer)
        {
            // Serialize Id
            writer.WriteAttributeString("Id", Id.ToString());

            // Serialize Children
            XmlSerializer childSerializer = new XmlSerializer(typeof(Child));
            foreach (Child child in Children)
            {
                childSerializer.Serialize(writer, child);
            }
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Child c1 = new Child { Id = Guid.NewGuid() };
            Child c2 = new Child { Id = Guid.NewGuid() };

            Parent p = new Parent { Id = Guid.NewGuid(), Children = new List<Child> { c1, c2 } };

            c1.parent = p;
            c2.parent = p;

            using (var stream1 = new MemoryStream())
            {
                XmlSerializer formatter = new XmlSerializer(typeof(Parent), new Type[] { typeof(Child) }) ;
                formatter.Serialize(stream1, p);
                stream1.Position = 0;

                stream1.Position = 0;

                var deserializedParent = formatter.Deserialize(stream1) as Parent;
                foreach (var child in deserializedParent.Children)
                {
                    Console.WriteLine(string.Format("Child Id: {0}, Parent Id: {1}", child.Id,  child.parent.Id ));
                }
            }

            Console.ReadLine();
        }

    }
}

Όταν χρησιμοποιείτε το DataContractSerializer, χρησιμοποιήστε το IsReference ιδιότητα του DataContractχαρακτηριστικού για να ενεργοποιήσετε την παρακολούθηση αναφορά κατά συνέχειες και deserializing DataContracts.

using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;

[DataContract(IsReference = true)]
public class Child
{
    [DataMember]
    public Guid Id { get; set; }

    [DataMember]
    public Parent parent;
}

[DataContract(IsReference = true)]
public class Parent
{
    [DataMember]
    public Guid Id;

    [DataMember]
    public List<Child> Children;
}

class Program
{
    static void Main(string[] args)
    {
        Child c1 = new Child { Id = Guid.NewGuid() };
        Child c2 = new Child { Id = Guid.NewGuid() };

        Parent p = new Parent { Id = Guid.NewGuid(), Children = new List<Child> { c1, c2 } };

        c1.parent = p;
        c2.parent = p;

        using (var stream1 = new MemoryStream())
        {
            DataContractSerializer formatter = new DataContractSerializer(typeof(Parent));
            formatter.WriteObject(stream1, p);
            stream1.Position = 0;

            var deserializedParent = formatter.ReadObject(stream1) as Parent;
            foreach (var child in deserializedParent.Children)
            {
                Console.WriteLine("Child Id: {0}, Parent Id: {1}", child.Id, child.parent.Id);
            }
        }

        Console.ReadLine();
    }

}
Απαντήθηκε 16/03/2012 στις 20:37
πηγή χρήστη

ψήφοι
2

Αν η αυτόματη deserialization δεν λειτουργεί, θα μπορούσατε να έχετε τάξη μητρική σας την εφαρμογή του interface IDeserializationCallback και ενημέρωση των παιδιών στην μέθοδο OnDeserialization .

[Serializable]
class Parent : IDeserializationCallback 
{
  public List<child> children;

  void IDeserializationCallback.OnDeserialization(Object sender) 
  {
    if (null != children)
    {
      children.ForEach(c => c.parent = this);
    }
  }
}
Απαντήθηκε 16/03/2012 στις 19:52
πηγή χρήστη

ψήφοι
2

Αν το αφήσετε μόνο του και ας Μητρική είναι μια δημόσια περιουσία ανάγνωσης / εγγραφής της τάξης παιδιών, ΝΕΤ διαδικασία αυτόματη σειριακή θα το χειριστεί σωστά.

Απαντήθηκε 09/12/2008 στις 18:28
πηγή χρήστη

ψήφοι
0

Θα καταφέρει αυτό (είδος) από επιτακτικούς τη μέθοδο Add στην κατηγορία συλλογή του αντικειμένου παιδιού, για να «ρυθμιστεί» η αξία των ακινήτων στην τάξη του παιδιού με το μοναδικό Κωδικός αναγνώρισης της μητρικής αντικειμένου

 public class Connections: List<Connection>
    {       public new void Add(Connection connection)
        {
            connection.ApplicationName = ApplicationName;
            base.Add(connection);
        }
    }
Απαντήθηκε 09/12/2008 στις 18:31
πηγή χρήστη

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more