mgholam / fastJSON

Smallest, fastest polymorphic JSON serializer
https://www.codeproject.com/Articles/159450/fastJSON-Smallest-Fastest-Polymorphic-JSON-Seriali
MIT License
478 stars 148 forks source link

Cannot deserialize object that overrides GetHashCode() #128

Open jhughes2112 opened 3 years ago

jhughes2112 commented 3 years ago

I have a complex object that needs to have only two fields need to be considered for the sortable order of the object. So I override int GetHashCode() and return a hash code constructed of those two fields. I get an exception here:

In ParseDictionary: JSON.cs (725) at "_circobj.TryGetValue(o, out circount) == false)"

o does not have any members set yet, so it dereferences null while calculating the hash for the object. I suppose I could provide a constructor, but the hash code would be meaningless at that point. I'm guessing this is how you handle circular references?

I "solved" this issue by taking the block at 725 and moving it just before the return, although I'm not certain it still works as you intended this way.

jhughes2112 commented 3 years ago

It looks like _cirrev is used for a rapid lookup of previous data, which unfortunately means I moved that block to the wrong place, as an array of identical structs is failing now. I'll keep tinkering with it, but I would appreciate a proper fix if you find time.

jhughes2112 commented 3 years ago

For reference, I kind of got there with setting InlineCircularReferences = true. At least now, all my data is written out and with the _cirobj dictionary being populated at the bottom of the ParseDictionary function, it handles my objects properly with an overridden GetHashCode() function.

mgholam commented 3 years ago

To be custom sort-able, I believe you only need to implement IComparable and IComparer interfaces.

jhughes2112 commented 3 years ago

That's a great tip. The situation is unchanged however. The time at which the class instance is added to a Dictionary, everything is null. Even if I default constructed all the members (strings) to be string.Empty, that runs the risk of colliding with another element that legitimately has empty members, since you're using .Add to put objects in the dictionary.

If you need an example class, I can send you one. That might be easier