-
Notifications
You must be signed in to change notification settings - Fork 4.9k
Replace collection instances on deserialize #39442
Replace collection instances on deserialize #39442
Conversation
{ | ||
public List<int> MyList { get; } = new List<int>(); | ||
// We don't attempt to deserialize into collections without a setter. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be something like "we replace the contents of this collection"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks. I will change in future PR to avoid CI reset.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks as a good fix, but this limits the serializer and makes it incompatible with others (see https://github.com/dotnet/corefx/issues/38435#issuecomment-504686914).
Sometimes business logic requires to have a collection which can't be null. So the user is forced to add a validator for that case or somehow handle this scenario in code. The last one can be done via the null coalesce operator (collection?.Any()
), but it makes migration to .NET 3.0 a bit harder.
So if there is no time to make it better, then I'm okay with it.
In #38797 I tried to fix the issue without introducing the breaking change. |
I created https://github.com/dotnet/corefx/issues/39477 to track that. This likely won't be for 3.0 since we already added full collection support throughout the product for all types of immutable collections, etc including derived types (cc @layomia). |
I'm having an interesting issue with this one: This test is failing: [TestMethod]
public void TestNullable()
{
string json = @"{""MyList"":[2,3]}";
ClassWithPopulatedListAndSetter obj = JsonSerializer.Deserialize<ClassWithPopulatedListAndSetter>(json);
Assert.AreEqual(2, obj.MyList.Length);
}
public class ClassWithPopulatedListAndSetter
{
private int[] myList = new int[] { 1 };
public int[] MyList
{
get => myList ??= Array.Empty<int>();
set => myList = value;
}
} While this is passing: [TestMethod]
public void TestNullable()
{
string json = @"{""MyList"":[2,3]}";
ClassWithPopulatedListAndSetter obj = JsonSerializer.Deserialize<ClassWithPopulatedListAndSetter>(json);
Assert.AreEqual(2, obj.MyList.Length);
}
public class ClassWithPopulatedListAndSetter
{
private int[] myList = new int[] { 1 };
public int[] MyList
{
get => myList;
set => myList = value;
}
} As you can see, I desperately want the returned value of the getter to be not null even when it is explicitly set to null before. I would expect both of the above cases to work but oddly enough, the first one is failing. Please feel free to look into that one @steveharter, I'm not sure if this would be something that you'd like to change. |
@serhatozgel - I am assuming you were trying this on 3.0/3.1. Is that correct? The issue you are seeing has already been fixed for 5.0 (I couldn't repro it against master). Could you try the latest nightly build of the SDK or add a package reference to the latest S.T.Json NuGet package from our nightly build feed: https://dotnetfeed.blob.core.windows.net/dotnet-core/index.json (e.g. version Does that work for you?
How is it failing? Are you seeing |
@ahsonkhan It was indeed that error message and I tested with 3.0 and 3.1. I'm glad it is fixed for 5.0. |
Fixes https://github.com/dotnet/corefx/issues/38435 the original issue with "Collection was of a fixed size" for pre-populated arrays.
In addition the semantics for how collections are materialized has changed:
Previously, pre-populated collections were appended to (when possible).
Replaces PR #38797. cc @YohDeadfall