C # seri kaldırma işleminde üst nesnesine işaretçiyi oluşturma

oy
4

Bir sınıfları gibi vardır:

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

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

Ben Ebeveyn deserialize, ben, yani ana başvuru olması için her çocuğun her istiyoruz. Soru seri kaldırma işleminde ben çocuğun üst set nerede işaretçisi, nedir? Ben deserialization hep varsayılan kurucu kullanması nedeniyle, çocuk için özel bir kurucu kullanmak gibi olamaz. Ben ISerializable uygulayan, o zaman alt nesneler zaten ebeveyn oluşturduğu andan tarafından oluşturulmuş gibi görünüyor. Bunu başarmak için başka bir yolu var mı?

Oluştur 09/12/2008 saat 18:20
kaynak kullanıcı
Diğer dillerde...                            


4 cevaplar

oy
8

Dairesel referanslar için farklı şekilde ele alınır BinaryFormatter, XmlSerializerve DataContractSerializer.

BinaryFormatterVarsayılan olarak destekler dairesel referanslar, hiçbir iş gerekli:

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();
    }
}

Kullanırken XmlSerializer, ebeveyne çocuğun başvurusu seri vermeyerek dairesel refernce önlemek ve ilişki seri kaldırma işlemi sırasında sabit olduğundan emin olun. Bu uygulayarak yapılır IXmlSerializablearayüz ve seri ve deserialization taşıma.

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();
        }

    }
}

Kullanırken DataContractSerializer, kullanmak IsReference özelliğini DataContractseri ve DataContracts deserializing zaman referans takibini sağlamak için nitelik.

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();
    }

}
Cevap 16/03/2012 saat 20:37
kaynak kullanıcı

oy
2

Otomatik deserialization çalışmazsa, sen Veli sınıfı uygulamak olabilir IDeserializationCallback arayüzü ve çocukları güncellemek OnDeserialization yöntemiyle .

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

  void IDeserializationCallback.OnDeserialization(Object sender) 
  {
    if (null != children)
    {
      children.ForEach(c => c.parent = this);
    }
  }
}
Cevap 16/03/2012 saat 19:52
kaynak kullanıcı

oy
2

Eğer yalnız bırakın ve Ebeveyn Çocuk sınıfının bir kamu okuma / yazma özelliği olsun, .NET otomatik seri süreci düzgün işleyecektir.

Cevap 09/12/2008 saat 18:28
kaynak kullanıcı

oy
0

Ben üst nesnenin benzersiz tanıtıcısında çocuk sınıfta bir özellik değeri "set' için, çocuk nesnenin toplama sınıfında Add yöntemini geçersiz kılarak bu (bir çeşit) başarılı

 public class Connections: List<Connection>
    {       public new void Add(Connection connection)
        {
            connection.ApplicationName = ApplicationName;
            base.Add(connection);
        }
    }
Cevap 09/12/2008 saat 18:31
kaynak kullanıcı

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