STJ: Preserving comparers with Immutable Dictionary/Set #55243
Replies: 1 comment
-
The problem here is what are you going to do if one of these collections is instantiated with I've actually had an idea around this for a while, and I'm curious if there's any merit: It starts with having some member on the built-in (concrete) public abstract partial class StringComparer
{
// Returns a known StringComparer based on the magic string, or null if the string didn't match
+ public static StringComparer? GetWellKnownComparer(string description);
} For serialization, things are a bit tricky.
Number 2 could probably be done with an attribute to instruct the (de)serializer: // This attribute doesn't exist, but take it as a strawman
[JsonCollection(IncludeComparerIfAble = true)]
public HashSet<string> Strings { get; init; }
// Has no effect, since it's entirely special-cased aroung String comparers (initially)
[JsonCollection(IncludeComparerIfAble = true)]
public HashSet<int> Ints { get; init; } Number 1 could be solved by way of a new interface: namespace System.Collections.Generic
{
public interface IKeyedCollection<in TKey> // Open question: extend 'IEnumerable<T>'?
{
IEqualityComparer<TKey> Comparer { get; }
}
} This would allow the relevant converter to do the following: // serialize
if (_includeComparer && collection is IKeyedCollection<string> { Comparer: StringComparer comparer })
{
// Write out the magic string as a json member
}
// deserialize
IEqualityComparer<TKey>? comparer;
if (_includeComparer && isStringKeyedCollection)
{
string? comparerDesc = /* Read the magic string */;
comparer = StringComparer.GetWellKnownComparer(comparerDesc);
} There's probably a number of holes in this idea, but I'm curious if those aren't insurmountable. Notes:
|
Beta Was this translation helpful? Give feedback.
-
Would it be possible to have the immutable collection deserializers enhanced so that they use the same Comparer of the original member?
(Please excuse typos. I'm on my phone)
For example:
Public Record Foo {
public ImmutableSet Member {get; init;} = ImmutableSet.Empty.WithComparer(StringComparer.InvariantCultureIgnoreCase);
}
When member is deserialized, preserve InvariantCultureIgnoreCase.
Or, alternatively, instead of creating a new ImmutableSet and replacing the existing one, just call Union on the existing one and assign to that value (so it would inherit initial values too).
Beta Was this translation helpful? Give feedback.
All reactions