Serialising and deserialising a custom type for Grasshopper

Hi,

similarly to Manipulator, I have a custom class D.
My goal is to have a GH component where you construct/build an instance of this class, which you get as an output. A second GH component, similar to the GH native component Data, would internalize the object instance. I am attaching the code that generates the first GH component and includes the class D (constructor fields etc.). Below you see the code for the second component. I cannot understand how to (de)serialize class fields like Point, Curve, Brep. Any hint/help in the Write, Read, Prompt_singular, Prompt_Plural methods would be much appreciated. Thanks!
BuildD.cs (3.6 KB)

public class SerializeD : GH_PersistentParam<D>
{
    public SerializeD(string name, string nickname, string description, string category, string subcategory)
        : base(name, nickname, description, category, subcategory) { }

    public SerializeD(GH_InstanceDescription tag) : base(tag) { }

    /// <summary>
    /// Initializes a new instance of the SerializeD class.
    /// </summary>
    public SerializeD()
      : base("Serialize D",
             "SerialD",
             "Description",
             "Category",
             "Subcategory")
    {
    }

    protected override GH_GetterResult Prompt_Singular(ref DGoo value) {
        return GH_GetterResult.cancel;
    }
    protected override GH_GetterResult Prompt_Plural(ref List<DGoo> values) {
        return GH_GetterResult.cancel;
    }

    protected override System.Drawing.Bitmap Icon
    {
        get
        {
            //You can add image files to your project resources and access them like this:
            // return Resources.IconForThisComponent;
            return null;
        }
    }

    public override Guid ComponentGuid
    {
        get { return new Guid("A80F4174-12B3-4CEB-B6C6-908326715BA7"); }
    }
}

public class DGoo : GH_Goo<D> {

    #region CONSTRUCTORS
    public DGoo()
        : this(null) { }
    public DGoo(D d) {
        Value = d;
    }
    #endregion

    #region PROPERTIES
    public override bool IsValid {
        get {
            if (Value.isEmpty) return false;
            return true;
        }
    }
    public override string TypeName => "D Ser";
    public override string TypeDescription => "Serialize D";
    public override IGH_Goo Duplicate() {
        // It's okay to share the same Foo instance since Foo is immutable.
        return new DGoo(Value);
    }
    public override string ToString() {
        if (Value == null) return "No d";
        return Value.ToString();
    }
    public override bool CastFrom(object source) {
        if (source.GetType() == typeof(D)) {
            Value = (D)source;
            return true;
        }

        if (source.GetType() == typeof(DGoo)) {
            Value = ((DGoo)source).Value;
            return true;
        }
        return base.CastFrom(source);
    }
    public override bool CastTo<Q>(ref Q target) {
        Type q = typeof(Q);
        if (typeof(Q) == typeof(D)) {
            target = (Q)(object)Value;
            return true;
        }

        if (typeof(Q) == typeof(DGoo)) {
            target = (Q)(object)this;
            return true;
        }

        return base.CastTo(ref target);
    }
    #endregion

    #region (DE)SERIALIZATION
    private string IoPointKey = "Point";
    private string IoCurvesKey;
    private string IoMeshesKey;

    public override bool Write(GH_IWriter writer) {
        if (!Value.isEmpty) {
            /*                
            Point3d pt = Value.Point;
            byte[] byteArrayP = GH_Convert.CommonObjectToByteArray<GeometryBase>(pt);
            writer.SetByteArray(IoPointKey, byteArrayP);
            */
            
            GH_Point3D gh_Point = new GH_Point3D(Value.Point.X, Value.Point.Y, Value.Point.Z);
            writer.SetPoint3D(IoPointKey, gh_Point);

            if (Value.Curves != null) {
                for (int i = 0; i < Value.Curves.Length; i++) {
                    IoCurvesKey = "Curve_" +  i.ToString();
                    byte[] byteArrayC = GH_Convert.CommonObjectToByteArray(Value.Curves[i]);
                    writer.SetByteArray(IoCurvesKey, byteArrayC);
                }                    
            }
            
            if (Value.Meshes != null) {
                for (int i = 0; i < Value.Meshes.Length; i++) {
                    IoMeshesKey = "Mesh_" + i.ToString();
                    byte[] byteArrayM = GH_Convert.CommonObjectToByteArray(Value.Meshes[i]);
                    writer.SetByteArray(IoMeshesKey, byteArrayM);
                }
            }
        }
        return true;
    }
    public override bool Read(GH_IReader reader) {

        GH_Point3D pt = reader.GetPoint3D(IoPointKey);
        List<Curve> curves = new List<Curve>();
        List<Rhino.Geometry.Mesh> meshes = new List<Rhino.Geometry.Mesh>();

        Value = new D(new Point3d(pt.x, pt.y, pt.z), curves, meshes);
        return true;
    }
    #endregion
}