Org.Grush.Lib.RecordCollections
0.3.0
dotnet add package Org.Grush.Lib.RecordCollections --version 0.3.0
NuGet\Install-Package Org.Grush.Lib.RecordCollections -Version 0.3.0
<PackageReference Include="Org.Grush.Lib.RecordCollections" Version="0.3.0" />
<PackageVersion Include="Org.Grush.Lib.RecordCollections" Version="0.3.0" />
<PackageReference Include="Org.Grush.Lib.RecordCollections" />
paket add Org.Grush.Lib.RecordCollections --version 0.3.0
#r "nuget: Org.Grush.Lib.RecordCollections, 0.3.0"
#:package Org.Grush.Lib.RecordCollections@0.3.0
#addin nuget:?package=Org.Grush.Lib.RecordCollections&version=0.3.0
#tool nuget:?package=Org.Grush.Lib.RecordCollections&version=0.3.0
RecordCollection<T>
A read-only, equatable, de/serializable, generic collection type for use in record classes.
TOC:
Initialization
RecordCollection
s can be initialized using the new collection expression approach:
RecordCollection<double> c = [3.14159, double.NaN, double.PositiveInfinity];
or using the static Create
methods, e.g.
var a = RecordCollection.Create(["a", "b", "c"]);
or using the LINQ-like extension on an existing IEnumerable:
List<int> oldList = [1, 2, 3];
var a = oldList.ToRecordCollection();
Equating
Two RecordCollection
s that are sequence-equal will return true from Equals()
:
RecordCollection<int> collectionA = [1, 2, 3];
var collectionB = RecordCollection.Create([1, 2, 3]);
var areEqual = collectionA.Equals(collectionB);
areEqual.Should().BeTrue();
This means that two records that contain RecordCollection<T>
properties are still equatable
record MyRecord(string Name, RecordCollection<string> Aliases);
MyRecord a = new("Joseph", ["Joe", "Joey"]);
MyRecord b = new("Joseph", ["Joe", "Joey"]);
var areEqual = a.Equals(b);
var areEqualsSign = a == b;
areEqual.Should().BeTrue();
areEqualsSign.Should().BeTrue();
additionally, RecordCollection<T>
s can be used in hash structures like HashSet
s:
HashSet<RecordCollection<double>> set = [
[1.1, 2.2]
];
var contains = set.Contains([1.1, 2.2]);
contains.Should().BeTrue();
Equals
rules:
- Calls to
RecordCollection<T>#Equals(object)
orRecordCollection<T>#Equals(object, IEqualityComparer<T>)
are only supported for otherRecordCollection<T>
. - Explicit calls to
((IStructuralEquatable)RecordCollection<T>)#Equals(object?, IEqualityComparer)
follow a priority order for checking:- if other implements
IEnumerable<T>
AND comparer implementsIEqualityComparer<T>
, we run a check using the<T>
-typed equality comparison. - if other implements
IEnumerable
not<T>
, a de-optimizedSequenceEqual
is used. - if other implements
IStructuralEquatable
, we call#GetHashCode(comparer)
on each instance and compare; NOTE: this eagerly evaluates the entire sequence.
- if other implements
Serialization
Serialization is implicitly supported by both System.Text.Json and Newtonsoft.
Deserialization
System.Text.Json
Reflection-based serialization is supported implicitly.
For AOT-compatible serialization the RecordCollectionStrictJsonConverter<T>
is provided by the core package:
using System.Text.Json;
using System.Text.Json.Serialization;
using Org.Grush.Lib.RecordCollections;
namespace TestProgram;
string jsonData =
"""
[{ "Name": "Joseph", "Alias": "Joey" }, { "Name": "Tom" }]
""";
RecordCollection<Datum>? data = JsonSerializer.Deserialize(
json: jsonData,
jsonTypeInfo: RecordCollectionOfDataContext.Default.RecordCollectionDatum
);
record Datum(string Name, string? Alias);
[JsonSourceGenerationOptions(WriteIndented = true, Converters = [typeof(RecordCollectionStrictJsonConverter<Datum>)])]
[JsonSerializable(typeof(RecordCollection<Datum>))]
[JsonSerializable(typeof(ImmutableArray<Datum>))]
[JsonSerializable(typeof(Datum))]
internal partial class RecordCollectionOfDataContext : JsonSerializerContext;
Newtonsoft
Newtonsoft deserialization is supported using the supplementary Org.Grush.Lib.RecordCollections.Newtonsoft
package,
either with the generic RecordCollectionNewtonsoftJsonConverterFactory
,
or if a specific type is known then RecordCollectionNewtonsoftJsonConverter<T>
converter can be used directly.
See the NuGet package or the GitHub source.
using Newtonsoft.Json;
using Org.Grush.Lib.RecordCollections.Newtonsoft;
namespace TestProgram;
string jsonData =
"""
{
"Strings": ["a", "b"],
"Ints": [1, 2]
}
""";
PairOfLists? pair1 = JsonConvert.DeserializeObject<PairOfLists>(jsonData, new JsonSerializerSettings
{
Converters = { new RecordCollectionNewtonsoftJsonConverterFactory() }
});
PairOfLists? pair2 = JsonConvert.DeserializeObject<PairOfLists>(jsonData, new JsonSerializerSettings
{
Converters = {
new RecordCollectionNewtonsoftJsonConverter<int>(),
new RecordCollectionNewtonsoftJsonConverter<string>(),
}
});
record PairOfLists(RecordCollection<string> Strings, RecordCollection<int> Ints);
Target Versions
Features differ subtly between target versions.
.NET 8+ version has no dependencies or shims, is AOT-compilation compatible, and supports the collection builder syntax.
.NET Standard 2.1 version requires two System NuGet packages, System.Collections.Immutable
and System.Text.Json
,
but supports .NET 5–7.
.NET Standard 2.0 version requires the above System NuGet packages and also the Microsoft.Bcl.HashCode
NuGet package,
loses some nullability checks,
but supports a significantly broader set of .NET versions including 4.6.1–4.8, Mono 5.4, and UWP.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
.NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
.NET Standard | netstandard2.0 is compatible. netstandard2.1 is compatible. |
.NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen40 was computed. tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- Microsoft.Bcl.HashCode (>= 1.0.0)
- System.Collections.Immutable (>= 8.0.0 && < 10.0.0)
- System.Text.Json (>= 8.0.5 && < 10.0.0)
-
.NETStandard 2.1
- System.Collections.Immutable (>= 8.0.0 && < 10.0.0)
- System.Text.Json (>= 8.0.5 && < 10.0.0)
-
net8.0
- System.Collections.Immutable (>= 8.0.0 && < 10.0.0)
- System.Text.Json (>= 8.0.5 && < 10.0.0)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on Org.Grush.Lib.RecordCollections:
Package | Downloads |
---|---|
Org.Grush.Lib.RecordCollections.Newtonsoft
Newtonsoft add-on for serializing Org.Grush.Lib.RecordCollections. |
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last Updated |
---|---|---|
0.3.0 | 140 | 2/5/2025 |
0.2.1 | 119 | 1/30/2025 |
0.1.0 | 128 | 1/29/2025 |
0.0.1-rc.7-split-validation | 69 | 1/29/2025 |
0.0.0-PR | 98 | 1/30/2025 |