Skip to content

Undocumented breaking change in .NET 5.0 - HashSet moved to another assembly/library #47113

@maciejjarzynski

Description

@maciejjarzynski

Hello everyone,
I've stumbled upon a breaking change which as far as I've searched for was not documented anywhere.
It seems that with that pull request #37180 HashSet was moved from System.Collections to System.Private.CoreLib library.
Let's say we have a fair big distributed system based on microservices with an immutable events used for a synchronization between them which are being stored forever.
Newtonsoft.Json is being used as a serializer/deserializer.
The problem with that breaking change is like in the example below:
that's an example of class which was serialized in a netcoreapp3.1 version (with a collection in a dictionary's value being HashSet):

public class TestClass
    {
        public IReadOnlyDictionary<string, IReadOnlyCollection<string>> Dictionary { get; }

        public TestClass(IReadOnlyDictionary<string, IReadOnlyCollection<string>> dictionary)
        {
            Dictionary = dictionary;
        }
    }

resulting in (with a collection in a dictionary's value being HashSet)

{
  "Dictionary": {
    "DictionaryKey": {
      "$type": "System.Collections.Generic.HashSet`1[[System.String, System.Private.CoreLib]], System.Collections",
      "$values": [
        "string value"
      ]
    }
  }
}

whereas in net5.0 it is being serialized as

{
  "Dictionary": {
    "DictionaryKey": {
      "$type": "System.Collections.Generic.HashSet`1[[System.String, System.Private.CoreLib]], System.Private.CoreLib",
      "$values": [
        "string value"
      ]
    }
  }
}

The TypeNameHandling is set to Auto.

The problem of couse occurs when trying to deserialize old-netcoreapp3.1 events/messages into the application running on net5.0

My questions are basically:

  • are there any other such an undocumented breaking changes, like any other types were moved between libraries?
  • are you aware that a mentioned change could have caused some serious implications and have some kind of solution or workaround for that?
  • @JamesNK maybe you'd have some idea, how could we disable the type name handling for the dictionaries and collections from a framework, so upon deserialization the $type would be ignored for those types?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions