How to Serialize a class contains a list of points for C#

How to Serialize a class contains a list of points for C#

ilovejingle
Enthusiast Enthusiast
2,056 Views
1 Reply
Message 1 of 2

How to Serialize a class contains a list of points for C#

ilovejingle
Enthusiast
Enthusiast

I have a simple class contains  a string name, and a list of point3D.

    [Serializable()]
    public class my_Volume:ISerializable
    {
        public my_Volume() { }
        public my_Volume(string name)
        {
            this.Name = name;
        }
        public string Name { get; set; }
        public List<Point3d> polyPoints { get; set; }

        //info is used to hold key value pairs.
        public void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            info.AddValue("Name", this.Name);
            info.AddValue("polyPoints", this.polyPoints);
        }
        public my_Volume(SerializationInfo info, StreamingContext context)
        {
            Name = (string)info.GetValue("Name",typeof(string));
            polyPoints = (List<Point3d>)info.GetValue("polyPoints", typeof(List<Point3d>));
        }
    }

I am trying to use a xml serializer to save it to a file. so I can retrieve it later on using the following code.

        public void cmdTest()
        {
            Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
            var vol = new my_Volume("CB5-3");
            vol.polyPoints = new List<Point3d>
            {
                new Point3d(0,0,0),
                new Point3d(0,1,0),
                new Point3d(0,0,1)
            };

            Stream stream = File.Open("Volume.dat", FileMode.Create);
            XmlSerializer serializer = new XmlSerializer(typeof(my_Volume));

            using (TextWriter tw = new StreamWriter(@"D:\myData.xml"))
            {
                serializer.Serialize(tw, vol);
            }

            vol = null;
            XmlSerializer deserializer = new XmlSerializer(typeof(my_Volume));
            using(TextReader reader = new StreamReader(@"D:\myData.xml"))
            {
                object obj = deserializer.Deserialize(reader);
                vol = (my_Volume)obj;
            }
            ed.WriteMessage(vol.polyPoints[0].ToString());
            ed.WriteMessage(vol.polyPoints[1].ToString());
            ed.WriteMessage(vol.polyPoints[2].ToString());
        }

Then I realize the list of points is not serialized. all the input becomes (0,0,0). 

Any reasons why this happens?

0 Likes
2,057 Views
1 Reply
Reply (1)
Message 2 of 2

_gile
Consultant
Consultant

Hi,

This is due to the fact the Point3d structure is not serializable.

You could use an array of double instead.

 

    [Serializable()]
    public class Volume : ISerializable
    {
        public string Name { get; set; }

        public List<double[]> PolyPoints { get; set; }

        public Volume()
        { }

        public Volume(string name, List<Point3d> points)
        {
            Name = name;
            PolyPoints = points.ConvertAll(p => p.ToArray());
        }

        public Volume(SerializationInfo info)
        {
            Name = info.GetString(nameof(Name));
            PolyPoints = (List<double[]>)info.GetValue(nameof(PolyPoints), typeof(List<double[]>));
        }

        public void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            info.AddValue(nameof(Name), Name);
            info.AddValue(nameof(PolyPoints), PolyPoints);
        }

        public List<Point3d> GetPoints() => PolyPoints.ConvertAll(p => new Point3d(p)).ToList();
    }
        [CommandMethod("CMD1")]
        public static void Cmd1()
        {
            var points = new List<Point3d>
            {
                new Point3d(0.0, 0.0, 0.0),
                new Point3d(0.0, 1.0, 0.0),
                new Point3d(0.0, 0.0, 1.0)
            };

            var vol = new Volume("CB5-3", points);

            var serializer = new XmlSerializer(typeof(Volume));

            using (TextWriter tw = new StreamWriter(@"D:\myData.xml"))
            {
                serializer.Serialize(tw, vol);
            }
        }

        [CommandMethod("CMD2")]
        public static void Cmd2()
        {
            var deserializer = new XmlSerializer(typeof(Volume));
            Volume vol;
            using (TextReader reader = new StreamReader(@"D:\myData.xml"))
            {
                vol = (Volume)deserializer.Deserialize(reader);
            }

            var ed = Application.DocumentManager.MdiActiveDocument.Editor;
            foreach (var point in vol.GetPoints())
            {
                ed.WriteMessage($"\n{point}");
            }
        }


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes