Add UserData: Object Reference not set to the instance of an object

Hi, I got this error when add UserData to the attributes of the object.

System.NullReferenceException: Object reference not set to an instance of an object.
   at Rhino.DocObjects.Custom.UserData.NonConstPointer(Boolean createIfMissing)
   at Rhino.DocObjects.Custom.UserDataList.Add(UserData userdata)

I am following this sample

MyUserData class is inherited from DocObjects.Custom.UserData

I am adding user data directly to the attributes of RhinoObject:
robj.Attributes.UserData.Add(MyUserData)

Where can be the problem?

I see it leads to UserData.NonConstPointer but no idea what is wrong there.

Thanks,
Dmitriy

Just digging a bit more i have found the following topic from @menno

Bug has been registered under: https://mcneel.myjetbrains.com/youtrack/issue/RH-23446
And I see the state is open.

@stevebaer, can you please comment? How to overcome this?
I am adding UserData from GH custom component.

This won’t be implemented any time soon. It will take quite a bit of core changes to allow for custom UserData to be defined by something other than a plug-in. I would recommend using the UserDictionary if at all possible.

Thank you, @stevebaer
It is a pity that it is even not planned so far as it limits possibility to write custom classes.

Is it any example of using UserDictionary for some Custom class which is a bit more complicated than key-string value?

Thanks,
Dmitriy

UserDictionary supports a lot more than just string values
http://developer.rhino3d.com/api/RhinoCommon/html/T_Rhino_Collections_ArchivableDictionary.htm

UserString on the other hand is just a dictionary of key/value pairs where all of the values are strings.

Thanks, @stevebaer

UserDictionary works quite good. The easiest solution I found is to serialize/deserialize custom class into/from Byte array.

This won’t be implemented any time soon. It will take quite a bit of core changes to allow for custom UserData to be defined by something other than a plug-in

Hi @stevebaer do you have any updates/plans about addressing this issue?

Hi @mingo1214,

It is highly doubtful this will change for Rhino 7. Can you use a user dictionary?

– Dale

@dale Thanks for letting me know, now it seems I have to use user dictionary then:>

Hi @dale, is there any way that I can do some cleaning up with ArchivableDictionary before it is being duplicated/Serialized ?

In UserData, I can override OnDuplicate/Serialize to do so, but this is not an option with ArchivableDictionary.

Thanks,
Mingbo

Hi @mingo1214,

Can you do this clean up in a RhinoDoc.BeginSaveDocument handler?

– Dale

@dale thanks, this will work.

Hi @dale,

There is one issue with this RhinoDoc.BeginSaveDocument, is there anyway to identify if this BeginSaveDocument is triggered before closing document?

Hi @stevebaer and @dale,

I just found out
MyUserData: Rhino.DocObjects.Custom.UserDictionary works within a separated dll library other than rhino plugin.

This surprises me because:
Rhino.DocObjects.Custom.UserDictionary inherits from Rhino.DocObjects.Custom.UserData, but MyUserData2: Rhino.DocObjects.Custom.UserData doesn’t work in a separated dll library (null reference exception when adding it to a geometry).

What’s main difference that makes this Rhino.DocObjects.Custom.UserDictionary useable, while Rhino.DocObjects.Custom.UserData doesn’t?

Is it safe to say: I can move from geometry.UserDictionary back to this custom MyUserData: Rhino.DocObjects.Custom.UserDictionary?

Thanks,
Mingbo

No, sorry that is not safe.

RhinoCommon has the full definition of what a UserDictionary is and knows how to perform all of the serialization of this data into an out of a 3dm file. This is not the case for your own custom userdata derived class. Custom user data has a Guid associated with it written in the 3dm file that tells it what plug-in defines that custom user data class, but for the actual serialization it is up to the plug-in to perform this task. We don’t have this concept in place for non-plugin support library DLLs

Thanks @stevebaer,

I did a little bit more tests today. Yes, there is no issue with adding MyUserData: Custom.UserDictionary to geometry, even this MyUserData is in non-plugin dll.

But as you said, it has issues that saving to 3dm file. The override Write of MyUserData: Custom.UserDictionary is called, I assume the data is saved to 3dm. But Read is never called, and cannot find any data anymore after reopen the file.

Thanks for your confirmation.
I guess I eventually have to give up on Custom.UseData.