Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Add support for types derived from supported BCL collections#39001

Merged
layomia merged 5 commits into
dotnet:masterfrom
layomia:derived_types
Jul 11, 2019
Merged

Add support for types derived from supported BCL collections#39001
layomia merged 5 commits into
dotnet:masterfrom
layomia:derived_types

Conversation

@layomia

@layomia layomia commented Jun 27, 2019

Copy link
Copy Markdown
Contributor

Fixes https://github.com/dotnet/corefx/issues/38767.
Fixes https://github.com/dotnet/corefx/issues/38521.

Supported in this PR: user-defined types that implement natively supported collections that have "add" methods e.g. IList<T>, Queue<T>, IDictionary, IList e tc.

Not supported in this PR: user-defined types that implement natively supported collections that don't have "add" methods e.g. IEnumerable<T>, ICollection, IReadOnyList<T> and immutable collections.

@layomia layomia added this to the 3.0 milestone Jun 27, 2019
@layomia layomia self-assigned this Jun 27, 2019
@danmoseley

Copy link
Copy Markdown
Member

At this point, is this required for 3.0? Is risk acceptable?

@layomia

layomia commented Jul 8, 2019

Copy link
Copy Markdown
Contributor Author

At this point, is this required for 3.0? Is risk acceptable?

Yes, it fixes some important issues raised by partners and community members, and it's pretty well tested.

https://github.com/dotnet/corefx/issues/38767.
https://github.com/dotnet/corefx/issues/38521.

@layomia layomia requested a review from steveharter July 8, 2019 23:10
@danmoseley

Copy link
Copy Markdown
Member

Ok.

@layomia layomia requested a review from JeremyKuhne July 9, 2019 15:30
@layomia

layomia commented Jul 9, 2019

Copy link
Copy Markdown
Contributor Author

cc @pranavkm

@layomia layomia added the json-functionality-doc Missing JSON specific functionality that needs documenting label Jul 9, 2019
Comment thread src/System.Text.Json/src/System/Text/Json/Serialization/JsonClassInfo.Helpers.cs Outdated
Comment thread src/System.Text.Json/src/System/Text/Json/Serialization/JsonClassInfo.Helpers.cs Outdated
Comment thread src/System.Text.Json/tests/Serialization/TestClasses.NonGenericCollections.cs Outdated
@layomia layomia merged commit 6005a1e into dotnet:master Jul 11, 2019
@layomia layomia deleted the derived_types branch July 25, 2019 18:09
@phizch

phizch commented Aug 18, 2019

Copy link
Copy Markdown

This change makes it impossible to have a JsonConverterFactory distinguish between a BCL base class and a derived type.

Specialized collections can be necessary if the json has multiple ways of declaring a list, e.g.

{
  "List1" : 
  {
    "Count": 50,
    "Values" : [ "test", ... ]
  },
  "List2" : [ "test", ... ] 
}
public class A
{
    public MyCollection List1 { get; set; }
    public List<string> List2 { get; set }
}
public class MyCollection : List<string> { }
public class MyConverterFactory : JsonConverterFactory
{
    public override bool CanConvert( Type typeToConvert )
    {
        return ( typeToConvert == typeof( MyCollection ) );
    }
    public override JsonConverter CreateConverter( Type typeToConvert, JsonSerializerOptions options )
    {
        // return the converter
        throw new NotImplementedException();
    }
}

From JsonClassInfo.AddProperty:

    // Get implemented type, if applicable.
    // Will return the propertyType itself if it's a non-enumerable, string, or natively supported collection.
    Type implementedType = GetImplementedCollectionType(propertyType);
    if (implementedType != propertyType)
    {
        jsonInfo = CreateProperty(implementedType, implementedType, implementedType, null, typeof(object), options);
    }
    else
    {
        jsonInfo = CreateProperty(propertyType, propertyType, propertyType, propertyInfo, classType, options);
    }

GetImplementedCollectionType(typeof(MyCollection)) will return List<string>, so CreateProperty will ask any factories to create converters for List.

A solution could be to provide CreateProperty and on to GetClassType with both implementedType and propertyType so that it can send propertyType to any factories, while using the BCL type if no factory can produce a converter for the derived type.

I don't know if I should have opened a new issue for this, but now at least you know..
If you'd like I can open a new issue and implement the changes.

@scalablecory

Copy link
Copy Markdown

@phizch this PR is closed and won't be tracked; please open a new issue for this. It's okay to reference this PR in that, though.

CC @ahsonkhan

@ahsonkhan

Copy link
Copy Markdown

If you'd like I can open a new issue

Yes, please.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area-System.Text.Json json-functionality-doc Missing JSON specific functionality that needs documenting

Projects

None yet

7 participants