HashSet<Guid> value in UserDictionary gets automatically converted into Guid[] on save/re-opening document

Hi,

I’m storing some Guids into Brep’s UserDictionary in form of a HashSet<Guid> value.

When I retrieve the UserDictionary right after having attached the Guids, the key value type is correct (HashSet<Guid>):

If I close and re-open the file and then retrieve the key, it appears to now an array Guid[]:

It is not a big issue as I still can store things into arrays, just wondering if it’s a normal behaviour…

Thanks!

System info:

Rhino 6 SR21 2019-11-25 (Rhino 6, 6.21.19329.23181, Git hash:master @ 71f4fdefc5a61567c57095484bdbf4af5244ed65)
License type: Commercial, build 2019-11-25
License details: LAN Zoo Network Node

Windows 10.0 SR0.0 or greater (Physical RAM: 32Gb)
Machine name: 

Non-hybrid graphics.
Primary display and OpenGL: NVIDIA Quadro P2000 (NVidia) Memory: 5GB, Driver date: 7-24-2019 (M-D-Y). OpenGL Ver: 4.6.0 NVIDIA 431.70

OpenGL Settings
  Safe mode: Off
  Use accelerated hardware modes: On
  Redraw scene when viewports are exposed: On
  
  Anti-alias mode: 8x
  Mip Map Filtering: Linear
  Anisotropic Filtering Mode: Height
  
  Vendor Name: NVIDIA Corporation
  Render version: 4.6
  Shading Language: 4.60 NVIDIA
  Driver Date: 7-24-2019
  Driver Version: 26.21.14.3170
  Maximum Texture size: 32768 x 32768
  Z-Buffer depth: 24 bits
  Maximum Viewport size: 32768 x 32768
  Total Video Memory: 5 GB

PS: it appears the same issue occurs with List<T> objects.

Hi @jeffoulet,

How are you adding the hashset to the dictionary? A code snippet would be helpful.

Thanks,

– Dale

Hi @dale,

Please see below:

Attach HashSet:

public override string EnglishName
        {
            get { return "clSampleAttachHashSet"; }
        }

        protected override Result RunCommand(RhinoDoc doc, RunMode mode)
        {
            var id1 = new Guid("9B2590F5-4BFF-44CF-8466-4B4250864744");
            var id2 = new Guid("E5011CCD-C046-4333-9605-1E853D795A33");
            var id3 = new Guid("F129DB00-D50C-40B4-B189-6BF13F06D5BA");

            var set = new HashSet<Guid>();
            set.Add(id1);
            set.Add(id2);
            set.Add(id3);

            var rc = RhinoGet.GetOneObject("Select object", false, ObjectType.AnyObject, out ObjRef objRef);
            if (rc != Result.Success)
            {
                return rc;
            }
            if (objRef == null)
            {
                return Result.Failure;
            }

            var obj = objRef.Object();
            if (obj == null)
            {
                return Result.Failure;
            }

            var dict = obj.Attributes.UserDictionary;
            if (!dict.ContainsKey("set"))
            {
                dict.Set("set", set);

                var type = dict["set"].ToString();
                RhinoApp.WriteLine(type);
            }            

            return Result.Success;
        }

Read HashSet:

 public override string EnglishName
        {
            get { return "clSampleReadHashset"; }
        }

        protected override Result RunCommand(RhinoDoc doc, RunMode mode)
        {
            var rc = RhinoGet.GetOneObject("Select object", false, ObjectType.AnyObject, out ObjRef objRef);
            if (rc != Result.Success)
            {
                return rc;
            }
            if (objRef == null)
            {
                return Result.Failure;
            }

            var obj = objRef.Object();
            if (obj == null)
            {
                return Result.Failure;
            }

            var dict = obj.Attributes.UserDictionary;
            if (dict.ContainsKey("set"))
            {
                var type = dict["set"].ToString();
                RhinoApp.WriteLine(type);
            }

            return Result.Success;
        }

Behaviour:

  • Attach + Read right after Attach:

image

  • Attach > Save > Close > Open > Read:

image

Hi @jeffoulet,

If you review the documentation for an ArchivableDictionary, you can see there is no Set member that accepts a HashSet.

However, there are a number of ArchivableDictionary.Set overrides that accept an IEnumerable collection. A HashSet does inherit from IEnumerable, which is why your setting code works.

Does this make sense?

– Dale