From 96d32a1b386dcfb6eece048f08e3d5a1dd663fcd Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Tue, 7 Jul 2026 18:37:33 +1000 Subject: [PATCH 1/3] IUnion --- apiCount.include.md | 2 +- api_list.include.md | 4 ++ assemblySize.include.md | 64 +++++++++---------- readme.md | 53 +++++++++++++++ src/ApiBuilderTests/BuildApiTest.cs | 2 + src/Consume/Consume.cs | 4 ++ src/Consume/Consume.csproj | 2 +- .../ConsumeNoOptional.csproj | 1 + src/Directory.Build.props | 1 + src/NoExtrasTests/NoExtrasTests.csproj | 1 + src/Polyfill/Polyfill.targets | 3 + src/Polyfill/Union/IUnion.cs | 26 ++++++++ src/Polyfill/Union/UnionAttribute.cs | 25 ++++++++ src/Split/net10.0/Union/IUnion.cs | 20 ++++++ src/Split/net10.0/Union/UnionAttribute.cs | 18 ++++++ src/Split/net11.0/TypeForwardeds.cs | 2 + src/Split/net461/Union/IUnion.cs | 20 ++++++ src/Split/net461/Union/UnionAttribute.cs | 18 ++++++ src/Split/net462/Union/IUnion.cs | 20 ++++++ src/Split/net462/Union/UnionAttribute.cs | 18 ++++++ src/Split/net47/Union/IUnion.cs | 20 ++++++ src/Split/net47/Union/UnionAttribute.cs | 18 ++++++ src/Split/net471/Union/IUnion.cs | 20 ++++++ src/Split/net471/Union/UnionAttribute.cs | 18 ++++++ src/Split/net472/Union/IUnion.cs | 20 ++++++ src/Split/net472/Union/UnionAttribute.cs | 18 ++++++ src/Split/net48/Union/IUnion.cs | 20 ++++++ src/Split/net48/Union/UnionAttribute.cs | 18 ++++++ src/Split/net481/Union/IUnion.cs | 20 ++++++ src/Split/net481/Union/UnionAttribute.cs | 18 ++++++ src/Split/net5.0/Union/IUnion.cs | 20 ++++++ src/Split/net5.0/Union/UnionAttribute.cs | 18 ++++++ src/Split/net6.0/Union/IUnion.cs | 20 ++++++ src/Split/net6.0/Union/UnionAttribute.cs | 18 ++++++ src/Split/net7.0/Union/IUnion.cs | 20 ++++++ src/Split/net7.0/Union/UnionAttribute.cs | 18 ++++++ src/Split/net8.0/Union/IUnion.cs | 20 ++++++ src/Split/net8.0/Union/UnionAttribute.cs | 18 ++++++ src/Split/net9.0/Union/IUnion.cs | 20 ++++++ src/Split/net9.0/Union/UnionAttribute.cs | 18 ++++++ src/Split/netcoreapp2.0/Union/IUnion.cs | 20 ++++++ .../netcoreapp2.0/Union/UnionAttribute.cs | 18 ++++++ src/Split/netcoreapp2.1/Union/IUnion.cs | 20 ++++++ .../netcoreapp2.1/Union/UnionAttribute.cs | 18 ++++++ src/Split/netcoreapp2.2/Union/IUnion.cs | 20 ++++++ .../netcoreapp2.2/Union/UnionAttribute.cs | 18 ++++++ src/Split/netcoreapp3.0/Union/IUnion.cs | 20 ++++++ .../netcoreapp3.0/Union/UnionAttribute.cs | 18 ++++++ src/Split/netcoreapp3.1/Union/IUnion.cs | 20 ++++++ .../netcoreapp3.1/Union/UnionAttribute.cs | 18 ++++++ src/Split/netstandard2.0/Union/IUnion.cs | 20 ++++++ .../netstandard2.0/Union/UnionAttribute.cs | 18 ++++++ src/Split/netstandard2.1/Union/IUnion.cs | 20 ++++++ .../netstandard2.1/Union/UnionAttribute.cs | 18 ++++++ src/Split/uap10.0/Union/IUnion.cs | 20 ++++++ src/Split/uap10.0/Union/UnionAttribute.cs | 18 ++++++ src/Tests/UnionTests.cs | 63 ++++++++++++++++++ 57 files changed, 1017 insertions(+), 34 deletions(-) create mode 100644 src/Polyfill/Union/IUnion.cs create mode 100644 src/Polyfill/Union/UnionAttribute.cs create mode 100644 src/Split/net10.0/Union/IUnion.cs create mode 100644 src/Split/net10.0/Union/UnionAttribute.cs create mode 100644 src/Split/net461/Union/IUnion.cs create mode 100644 src/Split/net461/Union/UnionAttribute.cs create mode 100644 src/Split/net462/Union/IUnion.cs create mode 100644 src/Split/net462/Union/UnionAttribute.cs create mode 100644 src/Split/net47/Union/IUnion.cs create mode 100644 src/Split/net47/Union/UnionAttribute.cs create mode 100644 src/Split/net471/Union/IUnion.cs create mode 100644 src/Split/net471/Union/UnionAttribute.cs create mode 100644 src/Split/net472/Union/IUnion.cs create mode 100644 src/Split/net472/Union/UnionAttribute.cs create mode 100644 src/Split/net48/Union/IUnion.cs create mode 100644 src/Split/net48/Union/UnionAttribute.cs create mode 100644 src/Split/net481/Union/IUnion.cs create mode 100644 src/Split/net481/Union/UnionAttribute.cs create mode 100644 src/Split/net5.0/Union/IUnion.cs create mode 100644 src/Split/net5.0/Union/UnionAttribute.cs create mode 100644 src/Split/net6.0/Union/IUnion.cs create mode 100644 src/Split/net6.0/Union/UnionAttribute.cs create mode 100644 src/Split/net7.0/Union/IUnion.cs create mode 100644 src/Split/net7.0/Union/UnionAttribute.cs create mode 100644 src/Split/net8.0/Union/IUnion.cs create mode 100644 src/Split/net8.0/Union/UnionAttribute.cs create mode 100644 src/Split/net9.0/Union/IUnion.cs create mode 100644 src/Split/net9.0/Union/UnionAttribute.cs create mode 100644 src/Split/netcoreapp2.0/Union/IUnion.cs create mode 100644 src/Split/netcoreapp2.0/Union/UnionAttribute.cs create mode 100644 src/Split/netcoreapp2.1/Union/IUnion.cs create mode 100644 src/Split/netcoreapp2.1/Union/UnionAttribute.cs create mode 100644 src/Split/netcoreapp2.2/Union/IUnion.cs create mode 100644 src/Split/netcoreapp2.2/Union/UnionAttribute.cs create mode 100644 src/Split/netcoreapp3.0/Union/IUnion.cs create mode 100644 src/Split/netcoreapp3.0/Union/UnionAttribute.cs create mode 100644 src/Split/netcoreapp3.1/Union/IUnion.cs create mode 100644 src/Split/netcoreapp3.1/Union/UnionAttribute.cs create mode 100644 src/Split/netstandard2.0/Union/IUnion.cs create mode 100644 src/Split/netstandard2.0/Union/UnionAttribute.cs create mode 100644 src/Split/netstandard2.1/Union/IUnion.cs create mode 100644 src/Split/netstandard2.1/Union/UnionAttribute.cs create mode 100644 src/Split/uap10.0/Union/IUnion.cs create mode 100644 src/Split/uap10.0/Union/UnionAttribute.cs create mode 100644 src/Tests/UnionTests.cs diff --git a/apiCount.include.md b/apiCount.include.md index 0c1cc2ed..d383e8af 100644 --- a/apiCount.include.md +++ b/apiCount.include.md @@ -1,4 +1,4 @@ -**API count: 1021** +**API count: 1023** ### Per Target Framework diff --git a/api_list.include.md b/api_list.include.md index 762d70f1..033364c3 100644 --- a/api_list.include.md +++ b/api_list.include.md @@ -1510,6 +1510,10 @@ #### UnreachableException +#### IUnion + +> Requires [`true`](#unions) in the consuming project. + #### StringStream #### ReadOnlyMemoryStream diff --git a/assemblySize.include.md b/assemblySize.include.md index 726651d6..951b5b7e 100644 --- a/assemblySize.include.md +++ b/assemblySize.include.md @@ -3,23 +3,23 @@ | | Empty Assembly | With Polyfill | Diff | Ensure | ArgumentExceptions | StringInterpolation | Nullability | |----------------|----------------|---------------|-----------|-----------|--------------------|---------------------|-------------| | netstandard2.0 | 8.0KB | 353.0KB | +345.0KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | -| netstandard2.1 | 8.5KB | 306.5KB | +298.0KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | -| net461 | 8.5KB | 351.5KB | +343.0KB | +9.0KB | +6.5KB | +9.5KB | +14.0KB | -| net462 | 7.0KB | 355.0KB | +348.0KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | +| netstandard2.1 | 8.5KB | 306.5KB | +298.0KB | +9.0KB | +6.5KB | +9.0KB | +14.0KB | +| net461 | 8.5KB | 351.5KB | +343.0KB | +9.5KB | +6.5KB | +9.5KB | +14.0KB | +| net462 | 7.0KB | 355.5KB | +348.5KB | +8.5KB | +6.5KB | +9.0KB | +13.5KB | | net47 | 7.0KB | 355.0KB | +348.0KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | -| net471 | 8.5KB | 354.0KB | +345.5KB | +8.0KB | +6.5KB | +9.0KB | +13.5KB | -| net472 | 8.5KB | 352.5KB | +344.0KB | +9.5KB | +6.5KB | +9.5KB | +14.0KB | -| net48 | 8.5KB | 352.5KB | +344.0KB | +9.5KB | +6.5KB | +9.5KB | +14.0KB | -| net481 | 8.5KB | 352.5KB | +344.0KB | +9.5KB | +6.5KB | +9.5KB | +14.0KB | -| netcoreapp2.0 | 9.0KB | 330.5KB | +321.5KB | +8.5KB | +6.0KB | +9.0KB | +13.5KB | -| netcoreapp2.1 | 9.0KB | 310.0KB | +301.0KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | -| netcoreapp2.2 | 9.0KB | 310.0KB | +301.0KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | -| netcoreapp3.0 | 9.5KB | 302.5KB | +293.0KB | +9.0KB | +6.5KB | +9.0KB | +14.0KB | -| netcoreapp3.1 | 9.5KB | 301.0KB | +291.5KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | -| net5.0 | 9.5KB | 265.0KB | +255.5KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | -| net6.0 | 10.0KB | 206.5KB | +196.5KB | +9.5KB | +7.0KB | +512bytes | +3.5KB | -| net7.0 | 10.0KB | 169.0KB | +159.0KB | +9.0KB | +5.5KB | +512bytes | +3.5KB | -| net8.0 | 9.5KB | 139.5KB | +130.0KB | +8.0KB | | +512bytes | +3.0KB | +| net471 | 8.5KB | 354.0KB | +345.5KB | +9.5KB | +6.5KB | +9.5KB | +14.0KB | +| net472 | 8.5KB | 353.0KB | +344.5KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | +| net48 | 8.5KB | 353.0KB | +344.5KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | +| net481 | 8.5KB | 353.0KB | +344.5KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | +| netcoreapp2.0 | 9.0KB | 330.5KB | +321.5KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | +| netcoreapp2.1 | 9.0KB | 310.0KB | +301.0KB | +9.0KB | +6.5KB | +9.0KB | +14.0KB | +| netcoreapp2.2 | 9.0KB | 310.0KB | +301.0KB | +9.0KB | +6.5KB | +9.0KB | +14.0KB | +| netcoreapp3.0 | 9.5KB | 303.0KB | +293.5KB | +8.5KB | +6.5KB | +9.0KB | +13.5KB | +| netcoreapp3.1 | 9.5KB | 301.0KB | +291.5KB | +9.0KB | +6.5KB | +9.0KB | +14.0KB | +| net5.0 | 9.5KB | 265.0KB | +255.5KB | +9.0KB | +6.5KB | +9.0KB | +14.0KB | +| net6.0 | 10.0KB | 206.5KB | +196.5KB | +10.0KB | +7.0KB | +512bytes | +3.5KB | +| net7.0 | 10.0KB | 169.0KB | +159.0KB | +9.5KB | +5.5KB | +512bytes | +3.5KB | +| net8.0 | 9.5KB | 139.5KB | +130.0KB | +8.5KB | +512bytes | +512bytes | +3.5KB | | net9.0 | 9.5KB | 92.5KB | +83.0KB | +8.5KB | | +512bytes | +3.5KB | | net10.0 | 10.0KB | 70.0KB | +60.0KB | +9.0KB | | +1.0KB | +3.5KB | | net11.0 | 10.0KB | 31.5KB | +21.5KB | +9.0KB | | +512bytes | +3.5KB | @@ -30,23 +30,23 @@ | | Empty Assembly | With Polyfill | Diff | Ensure | ArgumentExceptions | StringInterpolation | Nullability | |----------------|----------------|---------------|-----------|-----------|--------------------|---------------------|-------------| | netstandard2.0 | 8.0KB | 516.0KB | +508.0KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | -| netstandard2.1 | 8.5KB | 442.9KB | +434.4KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | -| net461 | 8.5KB | 515.6KB | +507.1KB | +16.7KB | +8.2KB | +14.4KB | +19.4KB | -| net462 | 7.0KB | 519.1KB | +512.1KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | +| netstandard2.1 | 8.5KB | 442.9KB | +434.4KB | +16.7KB | +8.2KB | +13.9KB | +19.4KB | +| net461 | 8.5KB | 515.6KB | +507.1KB | +17.2KB | +8.2KB | +14.4KB | +19.4KB | +| net462 | 7.0KB | 519.6KB | +512.6KB | +16.2KB | +8.2KB | +13.9KB | +18.9KB | | net47 | 7.0KB | 518.8KB | +511.8KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | -| net471 | 8.5KB | 517.5KB | +509.0KB | +15.7KB | +8.2KB | +13.9KB | +18.9KB | -| net472 | 8.5KB | 514.9KB | +506.4KB | +17.2KB | +8.2KB | +14.4KB | +19.4KB | -| net48 | 8.5KB | 514.9KB | +506.4KB | +17.2KB | +8.2KB | +14.4KB | +19.4KB | -| net481 | 8.5KB | 514.9KB | +506.4KB | +17.2KB | +8.2KB | +14.4KB | +19.4KB | -| netcoreapp2.0 | 9.0KB | 482.9KB | +473.9KB | +16.2KB | +7.7KB | +13.9KB | +18.9KB | -| netcoreapp2.1 | 9.0KB | 450.2KB | +441.2KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | -| netcoreapp2.2 | 9.0KB | 450.2KB | +441.2KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | -| netcoreapp3.0 | 9.5KB | 433.9KB | +424.4KB | +16.7KB | +8.2KB | +13.9KB | +19.4KB | -| netcoreapp3.1 | 9.5KB | 432.4KB | +422.9KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | -| net5.0 | 9.5KB | 378.2KB | +368.7KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | -| net6.0 | 10.0KB | 299.6KB | +289.6KB | +17.2KB | +8.7KB | +1.1KB | +4.2KB | -| net7.0 | 10.0KB | 243.5KB | +233.5KB | +16.6KB | +6.9KB | +1.1KB | +4.2KB | -| net8.0 | 9.5KB | 198.5KB | +189.0KB | +15.5KB | +299bytes | +1.1KB | +3.7KB | +| net471 | 8.5KB | 517.5KB | +509.0KB | +17.2KB | +8.2KB | +14.4KB | +19.4KB | +| net472 | 8.5KB | 515.4KB | +506.9KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | +| net48 | 8.5KB | 515.4KB | +506.9KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | +| net481 | 8.5KB | 515.4KB | +506.9KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | +| netcoreapp2.0 | 9.0KB | 482.9KB | +473.9KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | +| netcoreapp2.1 | 9.0KB | 450.2KB | +441.2KB | +16.7KB | +8.2KB | +13.9KB | +19.4KB | +| netcoreapp2.2 | 9.0KB | 450.2KB | +441.2KB | +16.7KB | +8.2KB | +13.9KB | +19.4KB | +| netcoreapp3.0 | 9.5KB | 434.4KB | +424.9KB | +16.2KB | +8.2KB | +13.9KB | +18.9KB | +| netcoreapp3.1 | 9.5KB | 432.4KB | +422.9KB | +16.7KB | +8.2KB | +13.9KB | +19.4KB | +| net5.0 | 9.5KB | 378.2KB | +368.7KB | +16.7KB | +8.2KB | +13.9KB | +19.4KB | +| net6.0 | 10.0KB | 299.6KB | +289.6KB | +17.7KB | +8.7KB | +1.1KB | +4.2KB | +| net7.0 | 10.0KB | 243.5KB | +233.5KB | +17.1KB | +6.9KB | +1.1KB | +4.2KB | +| net8.0 | 9.5KB | 198.5KB | +189.0KB | +16.0KB | +811bytes | +1.1KB | +4.2KB | | net9.0 | 9.5KB | 130.4KB | +120.9KB | +16.0KB | | +1.1KB | +4.2KB | | net10.0 | 10.0KB | 99.5KB | +89.5KB | +16.5KB | | +1.6KB | +4.2KB | | net11.0 | 10.0KB | 46.9KB | +36.9KB | +16.5KB | | +1.1KB | +4.2KB | diff --git a/readme.md b/readme.md index 199543e9..c9d3a827 100644 --- a/readme.md +++ b/readme.md @@ -524,6 +524,59 @@ Reference: [Improvements in native code interop in .NET 5.0](https://devblogs.mi * [DisableRuntimeMarshallingAttribute](https://learn.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.disableruntimemarshallingattribute) +### Unions + +Polyfills the two marker types that the compiler references when emitting [C# 15 union types](https://devblogs.microsoft.com/dotnet/csharp-15-union-types/), so unions can target older runtimes: + + * [UnionAttribute](https://learn.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.unionattribute) + * [IUnion](https://learn.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.iunion) + +This is opt-in. It is off by default to avoid clashing with the `UnionAttribute`/`IUnion` that current preview guidance has projects declare themselves. Enable it in the consuming project: + +```xml + + true + preview + +``` + +> Polyfill supplies only the `UnionAttribute` and `IUnion` types that the generated union struct references. The `union` keyword itself requires the C# 15 (or later) compiler and cannot be backported to an older compiler. + +Declaring a union: + +```cs +public union Pet(Cat, Dog, Bird); +``` + +Consuming a union, using the implicit conversion from a case type and pattern matching to unwrap it: + +```cs +Pet pet = new Dog("Rex"); + +var label = pet switch +{ + Cat cat => $"cat {cat.Name}", + Dog dog => $"dog {dog.Name}", + Bird bird => $"bird {bird.Name}" +}; +``` + +A union can also be declared explicitly using the polyfilled attribute and interface: + +```cs +[Union] +public readonly struct IntOrString : IUnion +{ + readonly object? value; + + public IntOrString(int value) => this.value = value; + public IntOrString(string value) => this.value = value; + + public object? Value => value; +} +``` + + ## Extensions The class `Polyfill` includes the following extension methods: diff --git a/src/ApiBuilderTests/BuildApiTest.cs b/src/ApiBuilderTests/BuildApiTest.cs index 77d97df2..c75853c2 100644 --- a/src/ApiBuilderTests/BuildApiTest.cs +++ b/src/ApiBuilderTests/BuildApiTest.cs @@ -23,6 +23,7 @@ public Task RunWithRoslyn() WriteHelper("Utf16", writer, ref count); WriteType(nameof(TaskCompletionSource), writer, ref count); WriteType(nameof(UnreachableException), writer, ref count); + WriteType("IUnion", writer, ref count); WriteType("StringStream", writer, ref count); WriteType("ReadOnlyMemoryStream", writer, ref count); WriteType("WritableMemoryStream", writer, ref count); @@ -311,6 +312,7 @@ static void WriteTypeMethods(string name, StreamWriter writer, ref int count, IE ["ArgumentOutOfRangeException"] = ("PolyArgumentExceptions", "argumentexception-1"), ["ObjectDisposedException"] = ("PolyArgumentExceptions", "argumentexception-1"), ["Ensure"] = ("PolyEnsure", "ensure-1"), + ["IUnion"] = ("PolyUnion", "unions"), }; static void WriteSectionGate(string sectionName, StreamWriter writer) diff --git a/src/Consume/Consume.cs b/src/Consume/Consume.cs index 1495f0f6..bb80efc1 100644 --- a/src/Consume/Consume.cs +++ b/src/Consume/Consume.cs @@ -103,6 +103,10 @@ class Consume type = typeof(RequiresUnreferencedCodeAttribute); type = typeof(UnconditionalSuppressMessageAttribute); type = typeof(CompilerFeatureRequiredAttribute); +#if PolyUnion + type = typeof(IUnion); + type = typeof(UnionAttribute); +#endif #if FeatureMemory type = typeof(CollectionBuilderAttribute); #endif diff --git a/src/Consume/Consume.csproj b/src/Consume/Consume.csproj index 9b4e448b..0e456852 100644 --- a/src/Consume/Consume.csproj +++ b/src/Consume/Consume.csproj @@ -2,7 +2,7 @@ $(NoWarn);PolyfillTargetsForNuget true - $(DefineConstants);PolyEnsure;PolyArgumentExceptions + $(DefineConstants);PolyEnsure;PolyArgumentExceptions;PolyUnion net461;net462;net47;net471;net472;net48;net481;net6.0-windows;netstandard2.0;netstandard2.1;netcoreapp2.0;netcoreapp2.1;netcoreapp2.2;netcoreapp3.0;netcoreapp3.1;net5.0;net6.0;net7.0;net8.0;net9.0;net10.0;net11.0 net481;netcoreapp3.1;net10.0;net11.0 diff --git a/src/ConsumeNoOptional/ConsumeNoOptional.csproj b/src/ConsumeNoOptional/ConsumeNoOptional.csproj index 8e72689a..dcb8a078 100644 --- a/src/ConsumeNoOptional/ConsumeNoOptional.csproj +++ b/src/ConsumeNoOptional/ConsumeNoOptional.csproj @@ -9,6 +9,7 @@ false false false + false $(DefineConstants);NoStringInterpolation diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 267bee81..eb070aa1 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -19,6 +19,7 @@ true true true + true true false enable diff --git a/src/NoExtrasTests/NoExtrasTests.csproj b/src/NoExtrasTests/NoExtrasTests.csproj index 293d3698..fdbedc32 100644 --- a/src/NoExtrasTests/NoExtrasTests.csproj +++ b/src/NoExtrasTests/NoExtrasTests.csproj @@ -8,6 +8,7 @@ false false false + false NoExtras diff --git a/src/Polyfill/Polyfill.targets b/src/Polyfill/Polyfill.targets index 88118b8a..c0264d92 100644 --- a/src/Polyfill/Polyfill.targets +++ b/src/Polyfill/Polyfill.targets @@ -166,6 +166,9 @@ For example: + + false diff --git a/src/Polyfill/Union/IUnion.cs b/src/Polyfill/Union/IUnion.cs new file mode 100644 index 00000000..fbc4dcd7 --- /dev/null +++ b/src/Polyfill/Union/IUnion.cs @@ -0,0 +1,26 @@ +#if !NET11_0_OR_GREATER +#nullable enable + +namespace System.Runtime.CompilerServices; + +/// +/// Provides a common interface for accessing the contents of a union type at runtime. +/// +#if PolyUseEmbeddedAttribute +[global::Microsoft.CodeAnalysis.EmbeddedAttribute] +#endif +//Link: https://learn.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.iunion?view=net-11.0 +#if PolyPublic +public +#endif +interface IUnion +{ + /// + /// Gets the value contained in the union, or if the union has no value. + /// + object? Value { get; } +} + +#else +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Runtime.CompilerServices.IUnion))] +#endif diff --git a/src/Polyfill/Union/UnionAttribute.cs b/src/Polyfill/Union/UnionAttribute.cs new file mode 100644 index 00000000..aeecb2b5 --- /dev/null +++ b/src/Polyfill/Union/UnionAttribute.cs @@ -0,0 +1,25 @@ +#if !NET11_0_OR_GREATER + +namespace System.Runtime.CompilerServices; + +using Diagnostics; +using Diagnostics.CodeAnalysis; + +/// +/// Indicates that a class or struct is a union type, enabling compiler support for union behaviors. +/// +[ExcludeFromCodeCoverage] +[DebuggerNonUserCode] +[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false, Inherited = false)] +#if PolyUseEmbeddedAttribute +[global::Microsoft.CodeAnalysis.EmbeddedAttribute] +#endif +//Link: https://learn.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.unionattribute?view=net-11.0 +#if PolyPublic +public +#endif +sealed class UnionAttribute : Attribute; + +#else +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Runtime.CompilerServices.UnionAttribute))] +#endif diff --git a/src/Split/net10.0/Union/IUnion.cs b/src/Split/net10.0/Union/IUnion.cs new file mode 100644 index 00000000..1a5691a4 --- /dev/null +++ b/src/Split/net10.0/Union/IUnion.cs @@ -0,0 +1,20 @@ +// +#pragma warning disable +#nullable enable +namespace System.Runtime.CompilerServices; +/// +/// Provides a common interface for accessing the contents of a union type at runtime. +/// +#if PolyUseEmbeddedAttribute +[global::Microsoft.CodeAnalysis.EmbeddedAttribute] +#endif +#if PolyPublic +public +#endif +interface IUnion +{ + /// + /// Gets the value contained in the union, or if the union has no value. + /// + object? Value { get; } +} diff --git a/src/Split/net10.0/Union/UnionAttribute.cs b/src/Split/net10.0/Union/UnionAttribute.cs new file mode 100644 index 00000000..6f79f10e --- /dev/null +++ b/src/Split/net10.0/Union/UnionAttribute.cs @@ -0,0 +1,18 @@ +// +#pragma warning disable +namespace System.Runtime.CompilerServices; +using Diagnostics; +using Diagnostics.CodeAnalysis; +/// +/// Indicates that a class or struct is a union type, enabling compiler support for union behaviors. +/// +[ExcludeFromCodeCoverage] +[DebuggerNonUserCode] +[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false, Inherited = false)] +#if PolyUseEmbeddedAttribute +[global::Microsoft.CodeAnalysis.EmbeddedAttribute] +#endif +#if PolyPublic +public +#endif +sealed class UnionAttribute : Attribute; diff --git a/src/Split/net11.0/TypeForwardeds.cs b/src/Split/net11.0/TypeForwardeds.cs index ac920b51..b08ba913 100644 --- a/src/Split/net11.0/TypeForwardeds.cs +++ b/src/Split/net11.0/TypeForwardeds.cs @@ -78,3 +78,5 @@ [assembly: TypeForwardedTo(typeof(System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute))] [assembly: TypeForwardedTo(typeof(System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute))] [assembly: TypeForwardedTo(typeof(System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessageAttribute))] +[assembly: TypeForwardedTo(typeof(System.Runtime.CompilerServices.IUnion))] +[assembly: TypeForwardedTo(typeof(System.Runtime.CompilerServices.UnionAttribute))] diff --git a/src/Split/net461/Union/IUnion.cs b/src/Split/net461/Union/IUnion.cs new file mode 100644 index 00000000..1a5691a4 --- /dev/null +++ b/src/Split/net461/Union/IUnion.cs @@ -0,0 +1,20 @@ +// +#pragma warning disable +#nullable enable +namespace System.Runtime.CompilerServices; +/// +/// Provides a common interface for accessing the contents of a union type at runtime. +/// +#if PolyUseEmbeddedAttribute +[global::Microsoft.CodeAnalysis.EmbeddedAttribute] +#endif +#if PolyPublic +public +#endif +interface IUnion +{ + /// + /// Gets the value contained in the union, or if the union has no value. + /// + object? Value { get; } +} diff --git a/src/Split/net461/Union/UnionAttribute.cs b/src/Split/net461/Union/UnionAttribute.cs new file mode 100644 index 00000000..6f79f10e --- /dev/null +++ b/src/Split/net461/Union/UnionAttribute.cs @@ -0,0 +1,18 @@ +// +#pragma warning disable +namespace System.Runtime.CompilerServices; +using Diagnostics; +using Diagnostics.CodeAnalysis; +/// +/// Indicates that a class or struct is a union type, enabling compiler support for union behaviors. +/// +[ExcludeFromCodeCoverage] +[DebuggerNonUserCode] +[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false, Inherited = false)] +#if PolyUseEmbeddedAttribute +[global::Microsoft.CodeAnalysis.EmbeddedAttribute] +#endif +#if PolyPublic +public +#endif +sealed class UnionAttribute : Attribute; diff --git a/src/Split/net462/Union/IUnion.cs b/src/Split/net462/Union/IUnion.cs new file mode 100644 index 00000000..1a5691a4 --- /dev/null +++ b/src/Split/net462/Union/IUnion.cs @@ -0,0 +1,20 @@ +// +#pragma warning disable +#nullable enable +namespace System.Runtime.CompilerServices; +/// +/// Provides a common interface for accessing the contents of a union type at runtime. +/// +#if PolyUseEmbeddedAttribute +[global::Microsoft.CodeAnalysis.EmbeddedAttribute] +#endif +#if PolyPublic +public +#endif +interface IUnion +{ + /// + /// Gets the value contained in the union, or if the union has no value. + /// + object? Value { get; } +} diff --git a/src/Split/net462/Union/UnionAttribute.cs b/src/Split/net462/Union/UnionAttribute.cs new file mode 100644 index 00000000..6f79f10e --- /dev/null +++ b/src/Split/net462/Union/UnionAttribute.cs @@ -0,0 +1,18 @@ +// +#pragma warning disable +namespace System.Runtime.CompilerServices; +using Diagnostics; +using Diagnostics.CodeAnalysis; +/// +/// Indicates that a class or struct is a union type, enabling compiler support for union behaviors. +/// +[ExcludeFromCodeCoverage] +[DebuggerNonUserCode] +[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false, Inherited = false)] +#if PolyUseEmbeddedAttribute +[global::Microsoft.CodeAnalysis.EmbeddedAttribute] +#endif +#if PolyPublic +public +#endif +sealed class UnionAttribute : Attribute; diff --git a/src/Split/net47/Union/IUnion.cs b/src/Split/net47/Union/IUnion.cs new file mode 100644 index 00000000..1a5691a4 --- /dev/null +++ b/src/Split/net47/Union/IUnion.cs @@ -0,0 +1,20 @@ +// +#pragma warning disable +#nullable enable +namespace System.Runtime.CompilerServices; +/// +/// Provides a common interface for accessing the contents of a union type at runtime. +/// +#if PolyUseEmbeddedAttribute +[global::Microsoft.CodeAnalysis.EmbeddedAttribute] +#endif +#if PolyPublic +public +#endif +interface IUnion +{ + /// + /// Gets the value contained in the union, or if the union has no value. + /// + object? Value { get; } +} diff --git a/src/Split/net47/Union/UnionAttribute.cs b/src/Split/net47/Union/UnionAttribute.cs new file mode 100644 index 00000000..6f79f10e --- /dev/null +++ b/src/Split/net47/Union/UnionAttribute.cs @@ -0,0 +1,18 @@ +// +#pragma warning disable +namespace System.Runtime.CompilerServices; +using Diagnostics; +using Diagnostics.CodeAnalysis; +/// +/// Indicates that a class or struct is a union type, enabling compiler support for union behaviors. +/// +[ExcludeFromCodeCoverage] +[DebuggerNonUserCode] +[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false, Inherited = false)] +#if PolyUseEmbeddedAttribute +[global::Microsoft.CodeAnalysis.EmbeddedAttribute] +#endif +#if PolyPublic +public +#endif +sealed class UnionAttribute : Attribute; diff --git a/src/Split/net471/Union/IUnion.cs b/src/Split/net471/Union/IUnion.cs new file mode 100644 index 00000000..1a5691a4 --- /dev/null +++ b/src/Split/net471/Union/IUnion.cs @@ -0,0 +1,20 @@ +// +#pragma warning disable +#nullable enable +namespace System.Runtime.CompilerServices; +/// +/// Provides a common interface for accessing the contents of a union type at runtime. +/// +#if PolyUseEmbeddedAttribute +[global::Microsoft.CodeAnalysis.EmbeddedAttribute] +#endif +#if PolyPublic +public +#endif +interface IUnion +{ + /// + /// Gets the value contained in the union, or if the union has no value. + /// + object? Value { get; } +} diff --git a/src/Split/net471/Union/UnionAttribute.cs b/src/Split/net471/Union/UnionAttribute.cs new file mode 100644 index 00000000..6f79f10e --- /dev/null +++ b/src/Split/net471/Union/UnionAttribute.cs @@ -0,0 +1,18 @@ +// +#pragma warning disable +namespace System.Runtime.CompilerServices; +using Diagnostics; +using Diagnostics.CodeAnalysis; +/// +/// Indicates that a class or struct is a union type, enabling compiler support for union behaviors. +/// +[ExcludeFromCodeCoverage] +[DebuggerNonUserCode] +[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false, Inherited = false)] +#if PolyUseEmbeddedAttribute +[global::Microsoft.CodeAnalysis.EmbeddedAttribute] +#endif +#if PolyPublic +public +#endif +sealed class UnionAttribute : Attribute; diff --git a/src/Split/net472/Union/IUnion.cs b/src/Split/net472/Union/IUnion.cs new file mode 100644 index 00000000..1a5691a4 --- /dev/null +++ b/src/Split/net472/Union/IUnion.cs @@ -0,0 +1,20 @@ +// +#pragma warning disable +#nullable enable +namespace System.Runtime.CompilerServices; +/// +/// Provides a common interface for accessing the contents of a union type at runtime. +/// +#if PolyUseEmbeddedAttribute +[global::Microsoft.CodeAnalysis.EmbeddedAttribute] +#endif +#if PolyPublic +public +#endif +interface IUnion +{ + /// + /// Gets the value contained in the union, or if the union has no value. + /// + object? Value { get; } +} diff --git a/src/Split/net472/Union/UnionAttribute.cs b/src/Split/net472/Union/UnionAttribute.cs new file mode 100644 index 00000000..6f79f10e --- /dev/null +++ b/src/Split/net472/Union/UnionAttribute.cs @@ -0,0 +1,18 @@ +// +#pragma warning disable +namespace System.Runtime.CompilerServices; +using Diagnostics; +using Diagnostics.CodeAnalysis; +/// +/// Indicates that a class or struct is a union type, enabling compiler support for union behaviors. +/// +[ExcludeFromCodeCoverage] +[DebuggerNonUserCode] +[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false, Inherited = false)] +#if PolyUseEmbeddedAttribute +[global::Microsoft.CodeAnalysis.EmbeddedAttribute] +#endif +#if PolyPublic +public +#endif +sealed class UnionAttribute : Attribute; diff --git a/src/Split/net48/Union/IUnion.cs b/src/Split/net48/Union/IUnion.cs new file mode 100644 index 00000000..1a5691a4 --- /dev/null +++ b/src/Split/net48/Union/IUnion.cs @@ -0,0 +1,20 @@ +// +#pragma warning disable +#nullable enable +namespace System.Runtime.CompilerServices; +/// +/// Provides a common interface for accessing the contents of a union type at runtime. +/// +#if PolyUseEmbeddedAttribute +[global::Microsoft.CodeAnalysis.EmbeddedAttribute] +#endif +#if PolyPublic +public +#endif +interface IUnion +{ + /// + /// Gets the value contained in the union, or if the union has no value. + /// + object? Value { get; } +} diff --git a/src/Split/net48/Union/UnionAttribute.cs b/src/Split/net48/Union/UnionAttribute.cs new file mode 100644 index 00000000..6f79f10e --- /dev/null +++ b/src/Split/net48/Union/UnionAttribute.cs @@ -0,0 +1,18 @@ +// +#pragma warning disable +namespace System.Runtime.CompilerServices; +using Diagnostics; +using Diagnostics.CodeAnalysis; +/// +/// Indicates that a class or struct is a union type, enabling compiler support for union behaviors. +/// +[ExcludeFromCodeCoverage] +[DebuggerNonUserCode] +[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false, Inherited = false)] +#if PolyUseEmbeddedAttribute +[global::Microsoft.CodeAnalysis.EmbeddedAttribute] +#endif +#if PolyPublic +public +#endif +sealed class UnionAttribute : Attribute; diff --git a/src/Split/net481/Union/IUnion.cs b/src/Split/net481/Union/IUnion.cs new file mode 100644 index 00000000..1a5691a4 --- /dev/null +++ b/src/Split/net481/Union/IUnion.cs @@ -0,0 +1,20 @@ +// +#pragma warning disable +#nullable enable +namespace System.Runtime.CompilerServices; +/// +/// Provides a common interface for accessing the contents of a union type at runtime. +/// +#if PolyUseEmbeddedAttribute +[global::Microsoft.CodeAnalysis.EmbeddedAttribute] +#endif +#if PolyPublic +public +#endif +interface IUnion +{ + /// + /// Gets the value contained in the union, or if the union has no value. + /// + object? Value { get; } +} diff --git a/src/Split/net481/Union/UnionAttribute.cs b/src/Split/net481/Union/UnionAttribute.cs new file mode 100644 index 00000000..6f79f10e --- /dev/null +++ b/src/Split/net481/Union/UnionAttribute.cs @@ -0,0 +1,18 @@ +// +#pragma warning disable +namespace System.Runtime.CompilerServices; +using Diagnostics; +using Diagnostics.CodeAnalysis; +/// +/// Indicates that a class or struct is a union type, enabling compiler support for union behaviors. +/// +[ExcludeFromCodeCoverage] +[DebuggerNonUserCode] +[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false, Inherited = false)] +#if PolyUseEmbeddedAttribute +[global::Microsoft.CodeAnalysis.EmbeddedAttribute] +#endif +#if PolyPublic +public +#endif +sealed class UnionAttribute : Attribute; diff --git a/src/Split/net5.0/Union/IUnion.cs b/src/Split/net5.0/Union/IUnion.cs new file mode 100644 index 00000000..1a5691a4 --- /dev/null +++ b/src/Split/net5.0/Union/IUnion.cs @@ -0,0 +1,20 @@ +// +#pragma warning disable +#nullable enable +namespace System.Runtime.CompilerServices; +/// +/// Provides a common interface for accessing the contents of a union type at runtime. +/// +#if PolyUseEmbeddedAttribute +[global::Microsoft.CodeAnalysis.EmbeddedAttribute] +#endif +#if PolyPublic +public +#endif +interface IUnion +{ + /// + /// Gets the value contained in the union, or if the union has no value. + /// + object? Value { get; } +} diff --git a/src/Split/net5.0/Union/UnionAttribute.cs b/src/Split/net5.0/Union/UnionAttribute.cs new file mode 100644 index 00000000..6f79f10e --- /dev/null +++ b/src/Split/net5.0/Union/UnionAttribute.cs @@ -0,0 +1,18 @@ +// +#pragma warning disable +namespace System.Runtime.CompilerServices; +using Diagnostics; +using Diagnostics.CodeAnalysis; +/// +/// Indicates that a class or struct is a union type, enabling compiler support for union behaviors. +/// +[ExcludeFromCodeCoverage] +[DebuggerNonUserCode] +[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false, Inherited = false)] +#if PolyUseEmbeddedAttribute +[global::Microsoft.CodeAnalysis.EmbeddedAttribute] +#endif +#if PolyPublic +public +#endif +sealed class UnionAttribute : Attribute; diff --git a/src/Split/net6.0/Union/IUnion.cs b/src/Split/net6.0/Union/IUnion.cs new file mode 100644 index 00000000..1a5691a4 --- /dev/null +++ b/src/Split/net6.0/Union/IUnion.cs @@ -0,0 +1,20 @@ +// +#pragma warning disable +#nullable enable +namespace System.Runtime.CompilerServices; +/// +/// Provides a common interface for accessing the contents of a union type at runtime. +/// +#if PolyUseEmbeddedAttribute +[global::Microsoft.CodeAnalysis.EmbeddedAttribute] +#endif +#if PolyPublic +public +#endif +interface IUnion +{ + /// + /// Gets the value contained in the union, or if the union has no value. + /// + object? Value { get; } +} diff --git a/src/Split/net6.0/Union/UnionAttribute.cs b/src/Split/net6.0/Union/UnionAttribute.cs new file mode 100644 index 00000000..6f79f10e --- /dev/null +++ b/src/Split/net6.0/Union/UnionAttribute.cs @@ -0,0 +1,18 @@ +// +#pragma warning disable +namespace System.Runtime.CompilerServices; +using Diagnostics; +using Diagnostics.CodeAnalysis; +/// +/// Indicates that a class or struct is a union type, enabling compiler support for union behaviors. +/// +[ExcludeFromCodeCoverage] +[DebuggerNonUserCode] +[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false, Inherited = false)] +#if PolyUseEmbeddedAttribute +[global::Microsoft.CodeAnalysis.EmbeddedAttribute] +#endif +#if PolyPublic +public +#endif +sealed class UnionAttribute : Attribute; diff --git a/src/Split/net7.0/Union/IUnion.cs b/src/Split/net7.0/Union/IUnion.cs new file mode 100644 index 00000000..1a5691a4 --- /dev/null +++ b/src/Split/net7.0/Union/IUnion.cs @@ -0,0 +1,20 @@ +// +#pragma warning disable +#nullable enable +namespace System.Runtime.CompilerServices; +/// +/// Provides a common interface for accessing the contents of a union type at runtime. +/// +#if PolyUseEmbeddedAttribute +[global::Microsoft.CodeAnalysis.EmbeddedAttribute] +#endif +#if PolyPublic +public +#endif +interface IUnion +{ + /// + /// Gets the value contained in the union, or if the union has no value. + /// + object? Value { get; } +} diff --git a/src/Split/net7.0/Union/UnionAttribute.cs b/src/Split/net7.0/Union/UnionAttribute.cs new file mode 100644 index 00000000..6f79f10e --- /dev/null +++ b/src/Split/net7.0/Union/UnionAttribute.cs @@ -0,0 +1,18 @@ +// +#pragma warning disable +namespace System.Runtime.CompilerServices; +using Diagnostics; +using Diagnostics.CodeAnalysis; +/// +/// Indicates that a class or struct is a union type, enabling compiler support for union behaviors. +/// +[ExcludeFromCodeCoverage] +[DebuggerNonUserCode] +[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false, Inherited = false)] +#if PolyUseEmbeddedAttribute +[global::Microsoft.CodeAnalysis.EmbeddedAttribute] +#endif +#if PolyPublic +public +#endif +sealed class UnionAttribute : Attribute; diff --git a/src/Split/net8.0/Union/IUnion.cs b/src/Split/net8.0/Union/IUnion.cs new file mode 100644 index 00000000..1a5691a4 --- /dev/null +++ b/src/Split/net8.0/Union/IUnion.cs @@ -0,0 +1,20 @@ +// +#pragma warning disable +#nullable enable +namespace System.Runtime.CompilerServices; +/// +/// Provides a common interface for accessing the contents of a union type at runtime. +/// +#if PolyUseEmbeddedAttribute +[global::Microsoft.CodeAnalysis.EmbeddedAttribute] +#endif +#if PolyPublic +public +#endif +interface IUnion +{ + /// + /// Gets the value contained in the union, or if the union has no value. + /// + object? Value { get; } +} diff --git a/src/Split/net8.0/Union/UnionAttribute.cs b/src/Split/net8.0/Union/UnionAttribute.cs new file mode 100644 index 00000000..6f79f10e --- /dev/null +++ b/src/Split/net8.0/Union/UnionAttribute.cs @@ -0,0 +1,18 @@ +// +#pragma warning disable +namespace System.Runtime.CompilerServices; +using Diagnostics; +using Diagnostics.CodeAnalysis; +/// +/// Indicates that a class or struct is a union type, enabling compiler support for union behaviors. +/// +[ExcludeFromCodeCoverage] +[DebuggerNonUserCode] +[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false, Inherited = false)] +#if PolyUseEmbeddedAttribute +[global::Microsoft.CodeAnalysis.EmbeddedAttribute] +#endif +#if PolyPublic +public +#endif +sealed class UnionAttribute : Attribute; diff --git a/src/Split/net9.0/Union/IUnion.cs b/src/Split/net9.0/Union/IUnion.cs new file mode 100644 index 00000000..1a5691a4 --- /dev/null +++ b/src/Split/net9.0/Union/IUnion.cs @@ -0,0 +1,20 @@ +// +#pragma warning disable +#nullable enable +namespace System.Runtime.CompilerServices; +/// +/// Provides a common interface for accessing the contents of a union type at runtime. +/// +#if PolyUseEmbeddedAttribute +[global::Microsoft.CodeAnalysis.EmbeddedAttribute] +#endif +#if PolyPublic +public +#endif +interface IUnion +{ + /// + /// Gets the value contained in the union, or if the union has no value. + /// + object? Value { get; } +} diff --git a/src/Split/net9.0/Union/UnionAttribute.cs b/src/Split/net9.0/Union/UnionAttribute.cs new file mode 100644 index 00000000..6f79f10e --- /dev/null +++ b/src/Split/net9.0/Union/UnionAttribute.cs @@ -0,0 +1,18 @@ +// +#pragma warning disable +namespace System.Runtime.CompilerServices; +using Diagnostics; +using Diagnostics.CodeAnalysis; +/// +/// Indicates that a class or struct is a union type, enabling compiler support for union behaviors. +/// +[ExcludeFromCodeCoverage] +[DebuggerNonUserCode] +[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false, Inherited = false)] +#if PolyUseEmbeddedAttribute +[global::Microsoft.CodeAnalysis.EmbeddedAttribute] +#endif +#if PolyPublic +public +#endif +sealed class UnionAttribute : Attribute; diff --git a/src/Split/netcoreapp2.0/Union/IUnion.cs b/src/Split/netcoreapp2.0/Union/IUnion.cs new file mode 100644 index 00000000..1a5691a4 --- /dev/null +++ b/src/Split/netcoreapp2.0/Union/IUnion.cs @@ -0,0 +1,20 @@ +// +#pragma warning disable +#nullable enable +namespace System.Runtime.CompilerServices; +/// +/// Provides a common interface for accessing the contents of a union type at runtime. +/// +#if PolyUseEmbeddedAttribute +[global::Microsoft.CodeAnalysis.EmbeddedAttribute] +#endif +#if PolyPublic +public +#endif +interface IUnion +{ + /// + /// Gets the value contained in the union, or if the union has no value. + /// + object? Value { get; } +} diff --git a/src/Split/netcoreapp2.0/Union/UnionAttribute.cs b/src/Split/netcoreapp2.0/Union/UnionAttribute.cs new file mode 100644 index 00000000..6f79f10e --- /dev/null +++ b/src/Split/netcoreapp2.0/Union/UnionAttribute.cs @@ -0,0 +1,18 @@ +// +#pragma warning disable +namespace System.Runtime.CompilerServices; +using Diagnostics; +using Diagnostics.CodeAnalysis; +/// +/// Indicates that a class or struct is a union type, enabling compiler support for union behaviors. +/// +[ExcludeFromCodeCoverage] +[DebuggerNonUserCode] +[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false, Inherited = false)] +#if PolyUseEmbeddedAttribute +[global::Microsoft.CodeAnalysis.EmbeddedAttribute] +#endif +#if PolyPublic +public +#endif +sealed class UnionAttribute : Attribute; diff --git a/src/Split/netcoreapp2.1/Union/IUnion.cs b/src/Split/netcoreapp2.1/Union/IUnion.cs new file mode 100644 index 00000000..1a5691a4 --- /dev/null +++ b/src/Split/netcoreapp2.1/Union/IUnion.cs @@ -0,0 +1,20 @@ +// +#pragma warning disable +#nullable enable +namespace System.Runtime.CompilerServices; +/// +/// Provides a common interface for accessing the contents of a union type at runtime. +/// +#if PolyUseEmbeddedAttribute +[global::Microsoft.CodeAnalysis.EmbeddedAttribute] +#endif +#if PolyPublic +public +#endif +interface IUnion +{ + /// + /// Gets the value contained in the union, or if the union has no value. + /// + object? Value { get; } +} diff --git a/src/Split/netcoreapp2.1/Union/UnionAttribute.cs b/src/Split/netcoreapp2.1/Union/UnionAttribute.cs new file mode 100644 index 00000000..6f79f10e --- /dev/null +++ b/src/Split/netcoreapp2.1/Union/UnionAttribute.cs @@ -0,0 +1,18 @@ +// +#pragma warning disable +namespace System.Runtime.CompilerServices; +using Diagnostics; +using Diagnostics.CodeAnalysis; +/// +/// Indicates that a class or struct is a union type, enabling compiler support for union behaviors. +/// +[ExcludeFromCodeCoverage] +[DebuggerNonUserCode] +[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false, Inherited = false)] +#if PolyUseEmbeddedAttribute +[global::Microsoft.CodeAnalysis.EmbeddedAttribute] +#endif +#if PolyPublic +public +#endif +sealed class UnionAttribute : Attribute; diff --git a/src/Split/netcoreapp2.2/Union/IUnion.cs b/src/Split/netcoreapp2.2/Union/IUnion.cs new file mode 100644 index 00000000..1a5691a4 --- /dev/null +++ b/src/Split/netcoreapp2.2/Union/IUnion.cs @@ -0,0 +1,20 @@ +// +#pragma warning disable +#nullable enable +namespace System.Runtime.CompilerServices; +/// +/// Provides a common interface for accessing the contents of a union type at runtime. +/// +#if PolyUseEmbeddedAttribute +[global::Microsoft.CodeAnalysis.EmbeddedAttribute] +#endif +#if PolyPublic +public +#endif +interface IUnion +{ + /// + /// Gets the value contained in the union, or if the union has no value. + /// + object? Value { get; } +} diff --git a/src/Split/netcoreapp2.2/Union/UnionAttribute.cs b/src/Split/netcoreapp2.2/Union/UnionAttribute.cs new file mode 100644 index 00000000..6f79f10e --- /dev/null +++ b/src/Split/netcoreapp2.2/Union/UnionAttribute.cs @@ -0,0 +1,18 @@ +// +#pragma warning disable +namespace System.Runtime.CompilerServices; +using Diagnostics; +using Diagnostics.CodeAnalysis; +/// +/// Indicates that a class or struct is a union type, enabling compiler support for union behaviors. +/// +[ExcludeFromCodeCoverage] +[DebuggerNonUserCode] +[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false, Inherited = false)] +#if PolyUseEmbeddedAttribute +[global::Microsoft.CodeAnalysis.EmbeddedAttribute] +#endif +#if PolyPublic +public +#endif +sealed class UnionAttribute : Attribute; diff --git a/src/Split/netcoreapp3.0/Union/IUnion.cs b/src/Split/netcoreapp3.0/Union/IUnion.cs new file mode 100644 index 00000000..1a5691a4 --- /dev/null +++ b/src/Split/netcoreapp3.0/Union/IUnion.cs @@ -0,0 +1,20 @@ +// +#pragma warning disable +#nullable enable +namespace System.Runtime.CompilerServices; +/// +/// Provides a common interface for accessing the contents of a union type at runtime. +/// +#if PolyUseEmbeddedAttribute +[global::Microsoft.CodeAnalysis.EmbeddedAttribute] +#endif +#if PolyPublic +public +#endif +interface IUnion +{ + /// + /// Gets the value contained in the union, or if the union has no value. + /// + object? Value { get; } +} diff --git a/src/Split/netcoreapp3.0/Union/UnionAttribute.cs b/src/Split/netcoreapp3.0/Union/UnionAttribute.cs new file mode 100644 index 00000000..6f79f10e --- /dev/null +++ b/src/Split/netcoreapp3.0/Union/UnionAttribute.cs @@ -0,0 +1,18 @@ +// +#pragma warning disable +namespace System.Runtime.CompilerServices; +using Diagnostics; +using Diagnostics.CodeAnalysis; +/// +/// Indicates that a class or struct is a union type, enabling compiler support for union behaviors. +/// +[ExcludeFromCodeCoverage] +[DebuggerNonUserCode] +[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false, Inherited = false)] +#if PolyUseEmbeddedAttribute +[global::Microsoft.CodeAnalysis.EmbeddedAttribute] +#endif +#if PolyPublic +public +#endif +sealed class UnionAttribute : Attribute; diff --git a/src/Split/netcoreapp3.1/Union/IUnion.cs b/src/Split/netcoreapp3.1/Union/IUnion.cs new file mode 100644 index 00000000..1a5691a4 --- /dev/null +++ b/src/Split/netcoreapp3.1/Union/IUnion.cs @@ -0,0 +1,20 @@ +// +#pragma warning disable +#nullable enable +namespace System.Runtime.CompilerServices; +/// +/// Provides a common interface for accessing the contents of a union type at runtime. +/// +#if PolyUseEmbeddedAttribute +[global::Microsoft.CodeAnalysis.EmbeddedAttribute] +#endif +#if PolyPublic +public +#endif +interface IUnion +{ + /// + /// Gets the value contained in the union, or if the union has no value. + /// + object? Value { get; } +} diff --git a/src/Split/netcoreapp3.1/Union/UnionAttribute.cs b/src/Split/netcoreapp3.1/Union/UnionAttribute.cs new file mode 100644 index 00000000..6f79f10e --- /dev/null +++ b/src/Split/netcoreapp3.1/Union/UnionAttribute.cs @@ -0,0 +1,18 @@ +// +#pragma warning disable +namespace System.Runtime.CompilerServices; +using Diagnostics; +using Diagnostics.CodeAnalysis; +/// +/// Indicates that a class or struct is a union type, enabling compiler support for union behaviors. +/// +[ExcludeFromCodeCoverage] +[DebuggerNonUserCode] +[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false, Inherited = false)] +#if PolyUseEmbeddedAttribute +[global::Microsoft.CodeAnalysis.EmbeddedAttribute] +#endif +#if PolyPublic +public +#endif +sealed class UnionAttribute : Attribute; diff --git a/src/Split/netstandard2.0/Union/IUnion.cs b/src/Split/netstandard2.0/Union/IUnion.cs new file mode 100644 index 00000000..1a5691a4 --- /dev/null +++ b/src/Split/netstandard2.0/Union/IUnion.cs @@ -0,0 +1,20 @@ +// +#pragma warning disable +#nullable enable +namespace System.Runtime.CompilerServices; +/// +/// Provides a common interface for accessing the contents of a union type at runtime. +/// +#if PolyUseEmbeddedAttribute +[global::Microsoft.CodeAnalysis.EmbeddedAttribute] +#endif +#if PolyPublic +public +#endif +interface IUnion +{ + /// + /// Gets the value contained in the union, or if the union has no value. + /// + object? Value { get; } +} diff --git a/src/Split/netstandard2.0/Union/UnionAttribute.cs b/src/Split/netstandard2.0/Union/UnionAttribute.cs new file mode 100644 index 00000000..6f79f10e --- /dev/null +++ b/src/Split/netstandard2.0/Union/UnionAttribute.cs @@ -0,0 +1,18 @@ +// +#pragma warning disable +namespace System.Runtime.CompilerServices; +using Diagnostics; +using Diagnostics.CodeAnalysis; +/// +/// Indicates that a class or struct is a union type, enabling compiler support for union behaviors. +/// +[ExcludeFromCodeCoverage] +[DebuggerNonUserCode] +[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false, Inherited = false)] +#if PolyUseEmbeddedAttribute +[global::Microsoft.CodeAnalysis.EmbeddedAttribute] +#endif +#if PolyPublic +public +#endif +sealed class UnionAttribute : Attribute; diff --git a/src/Split/netstandard2.1/Union/IUnion.cs b/src/Split/netstandard2.1/Union/IUnion.cs new file mode 100644 index 00000000..1a5691a4 --- /dev/null +++ b/src/Split/netstandard2.1/Union/IUnion.cs @@ -0,0 +1,20 @@ +// +#pragma warning disable +#nullable enable +namespace System.Runtime.CompilerServices; +/// +/// Provides a common interface for accessing the contents of a union type at runtime. +/// +#if PolyUseEmbeddedAttribute +[global::Microsoft.CodeAnalysis.EmbeddedAttribute] +#endif +#if PolyPublic +public +#endif +interface IUnion +{ + /// + /// Gets the value contained in the union, or if the union has no value. + /// + object? Value { get; } +} diff --git a/src/Split/netstandard2.1/Union/UnionAttribute.cs b/src/Split/netstandard2.1/Union/UnionAttribute.cs new file mode 100644 index 00000000..6f79f10e --- /dev/null +++ b/src/Split/netstandard2.1/Union/UnionAttribute.cs @@ -0,0 +1,18 @@ +// +#pragma warning disable +namespace System.Runtime.CompilerServices; +using Diagnostics; +using Diagnostics.CodeAnalysis; +/// +/// Indicates that a class or struct is a union type, enabling compiler support for union behaviors. +/// +[ExcludeFromCodeCoverage] +[DebuggerNonUserCode] +[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false, Inherited = false)] +#if PolyUseEmbeddedAttribute +[global::Microsoft.CodeAnalysis.EmbeddedAttribute] +#endif +#if PolyPublic +public +#endif +sealed class UnionAttribute : Attribute; diff --git a/src/Split/uap10.0/Union/IUnion.cs b/src/Split/uap10.0/Union/IUnion.cs new file mode 100644 index 00000000..1a5691a4 --- /dev/null +++ b/src/Split/uap10.0/Union/IUnion.cs @@ -0,0 +1,20 @@ +// +#pragma warning disable +#nullable enable +namespace System.Runtime.CompilerServices; +/// +/// Provides a common interface for accessing the contents of a union type at runtime. +/// +#if PolyUseEmbeddedAttribute +[global::Microsoft.CodeAnalysis.EmbeddedAttribute] +#endif +#if PolyPublic +public +#endif +interface IUnion +{ + /// + /// Gets the value contained in the union, or if the union has no value. + /// + object? Value { get; } +} diff --git a/src/Split/uap10.0/Union/UnionAttribute.cs b/src/Split/uap10.0/Union/UnionAttribute.cs new file mode 100644 index 00000000..6f79f10e --- /dev/null +++ b/src/Split/uap10.0/Union/UnionAttribute.cs @@ -0,0 +1,18 @@ +// +#pragma warning disable +namespace System.Runtime.CompilerServices; +using Diagnostics; +using Diagnostics.CodeAnalysis; +/// +/// Indicates that a class or struct is a union type, enabling compiler support for union behaviors. +/// +[ExcludeFromCodeCoverage] +[DebuggerNonUserCode] +[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false, Inherited = false)] +#if PolyUseEmbeddedAttribute +[global::Microsoft.CodeAnalysis.EmbeddedAttribute] +#endif +#if PolyPublic +public +#endif +sealed class UnionAttribute : Attribute; diff --git a/src/Tests/UnionTests.cs b/src/Tests/UnionTests.cs new file mode 100644 index 00000000..77e3c689 --- /dev/null +++ b/src/Tests/UnionTests.cs @@ -0,0 +1,63 @@ +using System.Reflection; + +public class UnionTests +{ + [Test] + public async Task IUnion_IsInterfaceExposingObjectValue() + { + var type = typeof(IUnion); + await Assert.That(type.IsInterface).IsTrue(); + + var property = type.GetProperty("Value"); + await Assert.That(property).IsNotNull(); + await Assert.That(property!.PropertyType).IsEqualTo(typeof(object)); + } + + [Test] + public async Task UnionAttribute_HasExpectedShape() + { + var type = typeof(UnionAttribute); + await Assert.That(type.IsSealed).IsTrue(); + await Assert.That(typeof(Attribute).IsAssignableFrom(type)).IsTrue(); + + var usage = type.GetCustomAttribute(); + await Assert.That(usage).IsNotNull(); + await Assert.That(usage!.ValidOn).IsEqualTo(AttributeTargets.Class | AttributeTargets.Struct); + await Assert.That(usage.AllowMultiple).IsFalse(); + await Assert.That(usage.Inherited).IsFalse(); + } + + [Test] + public async Task UserDefinedUnion_ValueRoundTrips() + { + IUnion fromInt = new IntOrString(5); + IUnion fromText = new IntOrString("text"); + + var intValue = fromInt.Value; + var textValue = fromText.Value; + + await Assert.That(intValue).IsEqualTo(5); + await Assert.That(textValue).IsEqualTo("text"); + } + + [Test] + public async Task UserDefinedUnion_IsMarkedAndImplementsIUnion() + { + var type = typeof(IntOrString); + + await Assert.That(type.GetCustomAttribute()).IsNotNull(); + await Assert.That(typeof(IUnion).IsAssignableFrom(type)).IsTrue(); + } + + [Union] + readonly struct IntOrString : IUnion + { + readonly object? value; + + public IntOrString(int value) => this.value = value; + + public IntOrString(string value) => this.value = value; + + public object? Value => value; + } +} From 4016426c1feb333edca9514879f07be99b370f94 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Wed, 9 Sep 2026 13:49:44 +1000 Subject: [PATCH 2/3] . --- apiCount.include.md | 44 ++++---- assemblySize.include.md | 44 ++++---- readme.md | 180 ++++++++++++++++++++------------- src/ConsumeCsPreview/Unions.cs | 48 +++++++++ src/Tests/UnionTests.cs | 4 + 5 files changed, 206 insertions(+), 114 deletions(-) create mode 100644 src/ConsumeCsPreview/Unions.cs diff --git a/apiCount.include.md b/apiCount.include.md index 1d791631..1b6bbe5a 100644 --- a/apiCount.include.md +++ b/apiCount.include.md @@ -1,28 +1,28 @@ -**API count: 1032** +**API count: 1034** ### Per Target Framework | Target | APIs | | -- | -- | -| `net461` | 974 | -| `net462` | 974 | -| `net47` | 973 | -| `net471` | 972 | -| `net472` | 968 | -| `net48` | 968 | -| `net481` | 968 | -| `netstandard2.0` | 970 | -| `netstandard2.1` | 823 | -| `netcoreapp2.0` | 893 | -| `netcoreapp2.1` | 834 | -| `netcoreapp2.2` | 834 | -| `netcoreapp3.0` | 786 | -| `netcoreapp3.1` | 785 | -| `net5.0` | 657 | -| `net6.0` | 558 | -| `net7.0` | 403 | -| `net8.0` | 284 | -| `net9.0` | 190 | -| `net10.0` | 136 | +| `net461` | 976 | +| `net462` | 976 | +| `net47` | 975 | +| `net471` | 974 | +| `net472` | 970 | +| `net48` | 970 | +| `net481` | 970 | +| `netstandard2.0` | 972 | +| `netstandard2.1` | 825 | +| `netcoreapp2.0` | 895 | +| `netcoreapp2.1` | 836 | +| `netcoreapp2.2` | 836 | +| `netcoreapp3.0` | 788 | +| `netcoreapp3.1` | 787 | +| `net5.0` | 659 | +| `net6.0` | 560 | +| `net7.0` | 405 | +| `net8.0` | 286 | +| `net9.0` | 192 | +| `net10.0` | 138 | | `net11.0` | 58 | -| `uap10.0` | 960 | +| `uap10.0` | 962 | diff --git a/assemblySize.include.md b/assemblySize.include.md index 339ab210..87d01d3b 100644 --- a/assemblySize.include.md +++ b/assemblySize.include.md @@ -22,31 +22,31 @@ | net8.0 | 9.5KB | 145.5KB | +136.0KB | +8.0KB | | +512bytes | +3.0KB | | net9.0 | 9.5KB | 98.5KB | +89.0KB | +8.5KB | | +512bytes | +3.0KB | | net10.0 | 10.0KB | 76.0KB | +66.0KB | +8.5KB | | +512bytes | +3.5KB | -| net11.0 | 10.0KB | 20.5KB | +10.5KB | +9.0KB | | +1.0KB | +3.5KB | +| net11.0 | 10.0KB | 21.0KB | +11.0KB | +9.0KB | | +512bytes | +3.5KB | ### Assembly Sizes with EmbedUntrackedSources | | Empty Assembly | With Polyfill | Diff | Ensure | ArgumentExceptions | StringInterpolation | Nullability | |----------------|----------------|---------------|-----------|-----------|--------------------|---------------------|-------------| -| netstandard2.0 | 8.0KB | 525.1KB | +517.1KB | +15.7KB | +8.2KB | +12.9KB | +17.9KB | -| netstandard2.1 | 8.5KB | 452.5KB | +444.0KB | +16.7KB | +8.2KB | +13.9KB | +19.4KB | -| net461 | 8.5KB | 525.2KB | +516.7KB | +15.2KB | +8.2KB | +12.4KB | +17.4KB | -| net462 | 7.0KB | 528.7KB | +521.7KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | -| net47 | 7.0KB | 527.9KB | +520.9KB | +17.2KB | +8.2KB | +14.4KB | +19.4KB | -| net471 | 8.5KB | 527.1KB | +518.6KB | +15.2KB | +8.2KB | +12.4KB | +17.4KB | -| net472 | 8.5KB | 524.5KB | +516.0KB | +15.2KB | +8.2KB | +12.9KB | +17.4KB | -| net48 | 8.5KB | 524.5KB | +516.0KB | +15.2KB | +8.2KB | +12.9KB | +17.4KB | -| net481 | 8.5KB | 524.5KB | +516.0KB | +15.2KB | +8.2KB | +12.9KB | +17.4KB | -| netcoreapp2.0 | 9.0KB | 492.1KB | +483.1KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | -| netcoreapp2.1 | 9.0KB | 459.7KB | +450.7KB | +16.7KB | +8.2KB | +13.9KB | +19.4KB | -| netcoreapp2.2 | 9.0KB | 459.7KB | +450.7KB | +16.7KB | +8.2KB | +14.4KB | +19.4KB | -| netcoreapp3.0 | 9.5KB | 444.3KB | +434.8KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | -| netcoreapp3.1 | 9.5KB | 442.3KB | +432.8KB | +16.7KB | +8.2KB | +13.9KB | +19.4KB | -| net5.0 | 9.5KB | 388.1KB | +378.6KB | +16.7KB | +8.2KB | +13.9KB | +19.4KB | -| net6.0 | 10.0KB | 309.4KB | +299.4KB | +17.2KB | +8.7KB | +1.1KB | +4.2KB | -| net7.0 | 10.0KB | 252.6KB | +242.6KB | +19.1KB | +9.4KB | +1.1KB | +3.7KB | -| net8.0 | 9.5KB | 207.6KB | +198.1KB | +15.5KB | +299bytes | +1.1KB | +3.7KB | -| net9.0 | 9.5KB | 139.5KB | +130.0KB | +16.0KB | | +1.1KB | +3.7KB | -| net10.0 | 10.0KB | 108.3KB | +98.3KB | +16.0KB | | +1.1KB | +4.2KB | -| net11.0 | 10.0KB | 30.4KB | +20.4KB | +16.5KB | | +1.6KB | +4.2KB | +| netstandard2.0 | 8.0KB | 525.8KB | +517.8KB | +15.7KB | +8.2KB | +12.9KB | +17.9KB | +| netstandard2.1 | 8.5KB | 453.1KB | +444.6KB | +16.7KB | +8.2KB | +13.9KB | +19.4KB | +| net461 | 8.5KB | 525.8KB | +517.3KB | +15.2KB | +8.2KB | +12.4KB | +17.4KB | +| net462 | 7.0KB | 529.3KB | +522.3KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | +| net47 | 7.0KB | 528.6KB | +521.6KB | +17.2KB | +8.2KB | +14.4KB | +19.4KB | +| net471 | 8.5KB | 527.7KB | +519.2KB | +15.2KB | +8.2KB | +12.4KB | +17.4KB | +| net472 | 8.5KB | 525.1KB | +516.6KB | +15.2KB | +8.2KB | +12.9KB | +17.4KB | +| net48 | 8.5KB | 525.1KB | +516.6KB | +15.2KB | +8.2KB | +12.9KB | +17.4KB | +| net481 | 8.5KB | 525.1KB | +516.6KB | +15.2KB | +8.2KB | +12.9KB | +17.4KB | +| netcoreapp2.0 | 9.0KB | 492.7KB | +483.7KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | +| netcoreapp2.1 | 9.0KB | 460.4KB | +451.4KB | +16.7KB | +8.2KB | +13.9KB | +19.4KB | +| netcoreapp2.2 | 9.0KB | 460.4KB | +451.4KB | +16.7KB | +8.2KB | +14.4KB | +19.4KB | +| netcoreapp3.0 | 9.5KB | 445.0KB | +435.5KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | +| netcoreapp3.1 | 9.5KB | 442.9KB | +433.4KB | +16.7KB | +8.2KB | +13.9KB | +19.4KB | +| net5.0 | 9.5KB | 388.8KB | +379.3KB | +16.7KB | +8.2KB | +13.9KB | +19.4KB | +| net6.0 | 10.0KB | 310.1KB | +300.1KB | +17.2KB | +8.7KB | +1.1KB | +4.2KB | +| net7.0 | 10.0KB | 253.2KB | +243.2KB | +19.1KB | +9.4KB | +1.1KB | +3.7KB | +| net8.0 | 9.5KB | 208.2KB | +198.7KB | +15.5KB | +299bytes | +1.1KB | +3.7KB | +| net9.0 | 9.5KB | 140.1KB | +130.6KB | +16.0KB | | +1.1KB | +3.7KB | +| net10.0 | 10.0KB | 108.9KB | +98.9KB | +16.0KB | | +1.1KB | +4.2KB | +| net11.0 | 10.0KB | 30.9KB | +20.9KB | +16.5KB | | +1.1KB | +4.2KB | diff --git a/readme.md b/readme.md index c4ef90b5..4898fc86 100644 --- a/readme.md +++ b/readme.md @@ -13,34 +13,34 @@ The package targets `netstandard2.0` and is designed to support the following ru * `uap10` -**API count: 1031** +**API count: 1034** ### Per Target Framework | Target | APIs | | -- | -- | -| `net461` | 973 | -| `net462` | 973 | -| `net47` | 972 | -| `net471` | 971 | -| `net472` | 967 | -| `net48` | 967 | -| `net481` | 967 | -| `netstandard2.0` | 969 | -| `netstandard2.1` | 822 | -| `netcoreapp2.0` | 892 | -| `netcoreapp2.1` | 833 | -| `netcoreapp2.2` | 833 | -| `netcoreapp3.0` | 785 | -| `netcoreapp3.1` | 784 | -| `net5.0` | 656 | -| `net6.0` | 557 | -| `net7.0` | 402 | -| `net8.0` | 283 | -| `net9.0` | 189 | -| `net10.0` | 135 | +| `net461` | 976 | +| `net462` | 976 | +| `net47` | 975 | +| `net471` | 974 | +| `net472` | 970 | +| `net48` | 970 | +| `net481` | 970 | +| `netstandard2.0` | 972 | +| `netstandard2.1` | 825 | +| `netcoreapp2.0` | 895 | +| `netcoreapp2.1` | 836 | +| `netcoreapp2.2` | 836 | +| `netcoreapp3.0` | 788 | +| `netcoreapp3.1` | 787 | +| `net5.0` | 659 | +| `net6.0` | 560 | +| `net7.0` | 405 | +| `net8.0` | 286 | +| `net9.0` | 192 | +| `net10.0` | 138 | | `net11.0` | 58 | -| `uap10.0` | 959 | +| `uap10.0` | 962 | @@ -96,54 +96,54 @@ This project uses features from the newest stable SDK and C# language. As such c | | Empty Assembly | With Polyfill | Diff | Ensure | ArgumentExceptions | StringInterpolation | Nullability | |----------------|----------------|---------------|-----------|-----------|--------------------|---------------------|-------------| -| netstandard2.0 | 8.0KB | 358.5KB | +350.5KB | +8.0KB | +7.0KB | +8.0KB | +12.5KB | -| netstandard2.1 | 8.5KB | 313.0KB | +304.5KB | +8.5KB | +6.5KB | +9.0KB | +13.5KB | -| net461 | 8.5KB | 357.5KB | +349.0KB | +7.5KB | +6.5KB | +8.0KB | +12.0KB | +| netstandard2.0 | 8.0KB | 358.5KB | +350.5KB | +8.0KB | +6.5KB | +8.0KB | +12.5KB | +| netstandard2.1 | 8.5KB | 312.5KB | +304.0KB | +9.0KB | +6.5KB | +9.0KB | +14.0KB | +| net461 | 8.5KB | 357.5KB | +349.0KB | +7.5KB | +6.5KB | +7.5KB | +12.0KB | | net462 | 7.0KB | 361.0KB | +354.0KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | -| net47 | 7.0KB | 361.0KB | +354.0KB | +9.0KB | +6.0KB | +9.0KB | +13.5KB | +| net47 | 7.0KB | 360.5KB | +353.5KB | +9.5KB | +6.5KB | +9.5KB | +14.0KB | | net471 | 8.5KB | 360.0KB | +351.5KB | +7.5KB | +6.5KB | +7.5KB | +12.0KB | -| net472 | 8.5KB | 358.5KB | +350.0KB | +7.5KB | +6.5KB | +8.0KB | +12.5KB | -| net48 | 8.5KB | 358.5KB | +350.0KB | +7.5KB | +6.5KB | +8.0KB | +12.5KB | -| net481 | 8.5KB | 358.5KB | +350.0KB | +8.0KB | +6.5KB | +8.0KB | +12.5KB | -| netcoreapp2.0 | 9.0KB | 336.5KB | +327.5KB | +8.5KB | +6.0KB | +8.5KB | +13.5KB | -| netcoreapp2.1 | 9.0KB | 316.5KB | +307.5KB | +8.5KB | +6.5KB | +9.0KB | +13.5KB | -| netcoreapp2.2 | 9.0KB | 316.5KB | +307.5KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | +| net472 | 8.5KB | 358.5KB | +350.0KB | +7.5KB | +6.5KB | +8.0KB | +12.0KB | +| net48 | 8.5KB | 358.5KB | +350.0KB | +7.5KB | +6.5KB | +8.0KB | +12.0KB | +| net481 | 8.5KB | 358.5KB | +350.0KB | +7.5KB | +6.5KB | +8.0KB | +12.0KB | +| netcoreapp2.0 | 9.0KB | 336.0KB | +327.0KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | +| netcoreapp2.1 | 9.0KB | 316.0KB | +307.0KB | +9.0KB | +6.5KB | +9.0KB | +14.0KB | +| netcoreapp2.2 | 9.0KB | 316.0KB | +307.0KB | +9.0KB | +6.5KB | +9.5KB | +14.0KB | | netcoreapp3.0 | 9.5KB | 309.5KB | +300.0KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | -| netcoreapp3.1 | 9.5KB | 308.0KB | +298.5KB | +8.5KB | +6.5KB | +9.0KB | +13.5KB | -| net5.0 | 9.5KB | 272.0KB | +262.5KB | +8.5KB | +6.5KB | +9.0KB | +13.5KB | -| net6.0 | 10.0KB | 213.0KB | +203.0KB | +10.0KB | +7.0KB | +512bytes | +3.5KB | +| netcoreapp3.1 | 9.5KB | 307.5KB | +298.0KB | +9.0KB | +6.5KB | +9.0KB | +14.0KB | +| net5.0 | 9.5KB | 271.5KB | +262.0KB | +9.0KB | +6.5KB | +9.0KB | +14.0KB | +| net6.0 | 10.0KB | 213.0KB | +203.0KB | +9.5KB | +7.0KB | +512bytes | +3.5KB | | net7.0 | 10.0KB | 175.0KB | +165.0KB | +11.5KB | +8.0KB | +512bytes | +3.0KB | -| net8.0 | 9.5KB | 145.5KB | +136.0KB | +8.5KB | | +512bytes | +3.0KB | -| net9.0 | 9.5KB | 98.5KB | +89.0KB | +8.5KB | | +512bytes | +3.5KB | +| net8.0 | 9.5KB | 145.5KB | +136.0KB | +8.0KB | | +512bytes | +3.0KB | +| net9.0 | 9.5KB | 98.5KB | +89.0KB | +8.5KB | | +512bytes | +3.0KB | | net10.0 | 10.0KB | 76.0KB | +66.0KB | +8.5KB | | +512bytes | +3.5KB | -| net11.0 | 10.0KB | 20.5KB | +10.5KB | +9.0KB | | +1.0KB | +3.5KB | +| net11.0 | 10.0KB | 21.0KB | +11.0KB | +9.0KB | | +512bytes | +3.5KB | ### Assembly Sizes with EmbedUntrackedSources | | Empty Assembly | With Polyfill | Diff | Ensure | ArgumentExceptions | StringInterpolation | Nullability | |----------------|----------------|---------------|-----------|-----------|--------------------|---------------------|-------------| -| netstandard2.0 | 8.0KB | 524.8KB | +516.8KB | +15.7KB | +8.7KB | +12.9KB | +17.9KB | -| netstandard2.1 | 8.5KB | 452.7KB | +444.2KB | +16.2KB | +8.2KB | +13.9KB | +18.9KB | -| net461 | 8.5KB | 524.9KB | +516.4KB | +15.2KB | +8.2KB | +12.9KB | +17.4KB | -| net462 | 7.0KB | 528.4KB | +521.4KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | -| net47 | 7.0KB | 528.1KB | +521.1KB | +16.7KB | +7.7KB | +13.9KB | +18.9KB | -| net471 | 8.5KB | 526.8KB | +518.3KB | +15.2KB | +8.2KB | +12.4KB | +17.4KB | -| net472 | 8.5KB | 524.2KB | +515.7KB | +15.2KB | +8.2KB | +12.9KB | +17.9KB | -| net48 | 8.5KB | 524.2KB | +515.7KB | +15.2KB | +8.2KB | +12.9KB | +17.9KB | -| net481 | 8.5KB | 524.2KB | +515.7KB | +15.7KB | +8.2KB | +12.9KB | +17.9KB | -| netcoreapp2.0 | 9.0KB | 492.3KB | +483.3KB | +16.2KB | +7.7KB | +13.4KB | +18.9KB | -| netcoreapp2.1 | 9.0KB | 459.9KB | +450.9KB | +16.2KB | +8.2KB | +13.9KB | +18.9KB | -| netcoreapp2.2 | 9.0KB | 459.9KB | +450.9KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | -| netcoreapp3.0 | 9.5KB | 444.0KB | +434.5KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | -| netcoreapp3.1 | 9.5KB | 442.5KB | +433.0KB | +16.2KB | +8.2KB | +13.9KB | +18.9KB | -| net5.0 | 9.5KB | 388.3KB | +378.8KB | +16.2KB | +8.2KB | +13.9KB | +18.9KB | -| net6.0 | 10.0KB | 309.1KB | +299.1KB | +17.7KB | +8.7KB | +1.1KB | +4.2KB | -| net7.0 | 10.0KB | 252.3KB | +242.3KB | +19.1KB | +9.4KB | +1.1KB | +3.7KB | -| net8.0 | 9.5KB | 207.3KB | +197.8KB | +16.0KB | +299bytes | +1.1KB | +3.7KB | -| net9.0 | 9.5KB | 139.1KB | +129.6KB | +16.0KB | | +1.1KB | +4.2KB | -| net10.0 | 10.0KB | 108.0KB | +98.0KB | +16.0KB | | +1.1KB | +4.2KB | -| net11.0 | 10.0KB | 30.4KB | +20.4KB | +16.5KB | | +1.6KB | +4.2KB | +| netstandard2.0 | 8.0KB | 525.8KB | +517.8KB | +15.7KB | +8.2KB | +12.9KB | +17.9KB | +| netstandard2.1 | 8.5KB | 453.1KB | +444.6KB | +16.7KB | +8.2KB | +13.9KB | +19.4KB | +| net461 | 8.5KB | 525.8KB | +517.3KB | +15.2KB | +8.2KB | +12.4KB | +17.4KB | +| net462 | 7.0KB | 529.3KB | +522.3KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | +| net47 | 7.0KB | 528.6KB | +521.6KB | +17.2KB | +8.2KB | +14.4KB | +19.4KB | +| net471 | 8.5KB | 527.7KB | +519.2KB | +15.2KB | +8.2KB | +12.4KB | +17.4KB | +| net472 | 8.5KB | 525.1KB | +516.6KB | +15.2KB | +8.2KB | +12.9KB | +17.4KB | +| net48 | 8.5KB | 525.1KB | +516.6KB | +15.2KB | +8.2KB | +12.9KB | +17.4KB | +| net481 | 8.5KB | 525.1KB | +516.6KB | +15.2KB | +8.2KB | +12.9KB | +17.4KB | +| netcoreapp2.0 | 9.0KB | 492.7KB | +483.7KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | +| netcoreapp2.1 | 9.0KB | 460.4KB | +451.4KB | +16.7KB | +8.2KB | +13.9KB | +19.4KB | +| netcoreapp2.2 | 9.0KB | 460.4KB | +451.4KB | +16.7KB | +8.2KB | +14.4KB | +19.4KB | +| netcoreapp3.0 | 9.5KB | 445.0KB | +435.5KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | +| netcoreapp3.1 | 9.5KB | 442.9KB | +433.4KB | +16.7KB | +8.2KB | +13.9KB | +19.4KB | +| net5.0 | 9.5KB | 388.8KB | +379.3KB | +16.7KB | +8.2KB | +13.9KB | +19.4KB | +| net6.0 | 10.0KB | 310.1KB | +300.1KB | +17.2KB | +8.7KB | +1.1KB | +4.2KB | +| net7.0 | 10.0KB | 253.2KB | +243.2KB | +19.1KB | +9.4KB | +1.1KB | +3.7KB | +| net8.0 | 9.5KB | 208.2KB | +198.7KB | +15.5KB | +299bytes | +1.1KB | +3.7KB | +| net9.0 | 9.5KB | 140.1KB | +130.6KB | +16.0KB | | +1.1KB | +3.7KB | +| net10.0 | 10.0KB | 108.9KB | +98.9KB | +16.0KB | | +1.1KB | +4.2KB | +| net11.0 | 10.0KB | 30.9KB | +20.9KB | +16.5KB | | +1.1KB | +4.2KB | @@ -544,37 +544,73 @@ This is opt-in. It is off by default to avoid clashing with the `UnionAttribute` Declaring a union: + + ```cs -public union Pet(Cat, Dog, Bird); +record Cat(string Name); + +record Dog(string Name); + +record Bird(string Name); + +union Pet(Cat, Dog, Bird); ``` +snippet source | anchor + Consuming a union, using the implicit conversion from a case type and pattern matching to unwrap it: + + ```cs -Pet pet = new Dog("Rex"); - -var label = pet switch +public static string Describe(Dog dog) { - Cat cat => $"cat {cat.Name}", - Dog dog => $"dog {dog.Name}", - Bird bird => $"bird {bird.Name}" -}; + // implicit conversion from one of the case types + Pet pet = dog; + + // no default arm: the switch is exhaustive because every case type is handled + return pet switch + { + Cat cat => $"cat {cat.Name}", + Dog other => $"dog {other.Name}", + Bird bird => $"bird {bird.Name}" + }; +} +``` +snippet source | anchor + + +The generated union struct implements `IUnion`, so the current value can also be read as an `object`: + + + +```cs +// every union implements IUnion, which exposes the current value as object +public static object? CurrentValue(Pet pet) => + ((IUnion) pet).Value; ``` +snippet source | anchor + A union can also be declared explicitly using the polyfilled attribute and interface: + + ```cs [Union] -public readonly struct IntOrString : IUnion +readonly struct IntOrString : IUnion { readonly object? value; public IntOrString(int value) => this.value = value; + public IntOrString(string value) => this.value = value; public object? Value => value; } ``` +snippet source | anchor + ## Extensions @@ -2115,6 +2151,10 @@ The class `Polyfill` includes the following extension methods: #### UnreachableException +#### IUnion + +> Requires [`true`](#unions) in the consuming project. + #### StringStream #### ReadOnlyMemoryStream @@ -2320,7 +2360,7 @@ void ObjectDisposedExceptionExample(bool isDisposed) ObjectDisposedException.ThrowIf(isDisposed, typeof(Consume)); } ``` -snippet source | anchor +snippet source | anchor @@ -2339,7 +2379,7 @@ void EnsureExample(Order order, Customer customer, string customerId, string ema this.quantity = Ensure.NotNegativeOrZero(quantity); } ``` -snippet source | anchor +snippet source | anchor diff --git a/src/ConsumeCsPreview/Unions.cs b/src/ConsumeCsPreview/Unions.cs new file mode 100644 index 00000000..5d44611c --- /dev/null +++ b/src/ConsumeCsPreview/Unions.cs @@ -0,0 +1,48 @@ +using System.Runtime.CompilerServices; + +namespace ConsumeCsPreview; + +// Compile-only coverage for C# union types. The compiler emits a struct that is +// annotated with UnionAttribute and implements IUnion, so this only compiles +// when both are polyfilled. + +#region UnionDeclaration + +record Cat(string Name); + +record Dog(string Name); + +record Bird(string Name); + +union Pet(Cat, Dog, Bird); + +#endregion + +static class Unions +{ + #region UnionUsage + + public static string Describe(Dog dog) + { + // implicit conversion from one of the case types + Pet pet = dog; + + // no default arm: the switch is exhaustive because every case type is handled + return pet switch + { + Cat cat => $"cat {cat.Name}", + Dog other => $"dog {other.Name}", + Bird bird => $"bird {bird.Name}" + }; + } + + #endregion + + #region UnionValue + + // every union implements IUnion, which exposes the current value as object + public static object? CurrentValue(Pet pet) => + ((IUnion) pet).Value; + + #endregion +} diff --git a/src/Tests/UnionTests.cs b/src/Tests/UnionTests.cs index 77e3c689..309b8cf9 100644 --- a/src/Tests/UnionTests.cs +++ b/src/Tests/UnionTests.cs @@ -49,6 +49,8 @@ public async Task UserDefinedUnion_IsMarkedAndImplementsIUnion() await Assert.That(typeof(IUnion).IsAssignableFrom(type)).IsTrue(); } + #region UnionExplicit + [Union] readonly struct IntOrString : IUnion { @@ -60,4 +62,6 @@ public async Task UserDefinedUnion_IsMarkedAndImplementsIUnion() public object? Value => value; } + + #endregion } From 0b71a1e1f89db13d37cc043d4967c8a63351615d Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Wed, 9 Sep 2026 14:26:26 +1000 Subject: [PATCH 3/3] . --- api_list.include.md | 2 - assemblySize.include.md | 80 +++++++-------- readme.md | 97 +++++++++---------- src/ApiBuilderTests/BuildApiTest.cs | 1 - src/Consume/Consume.cs | 2 - src/Consume/Consume.csproj | 2 +- .../ConsumeNoOptional.csproj | 1 - src/Directory.Build.props | 1 - src/NoExtrasTests/NoExtrasTests.csproj | 1 - src/Polyfill/{Union => }/IUnion.cs | 0 src/Polyfill/Polyfill.targets | 3 - src/Polyfill/{Union => }/UnionAttribute.cs | 0 src/Split/net10.0/{Union => }/IUnion.cs | 0 .../net10.0/{Union => }/UnionAttribute.cs | 0 src/Split/net11.0/TypeForwardeds.cs | 4 +- src/Split/net461/{Union => }/IUnion.cs | 0 .../net461/{Union => }/UnionAttribute.cs | 0 src/Split/net462/{Union => }/IUnion.cs | 0 .../net462/{Union => }/UnionAttribute.cs | 0 src/Split/net47/{Union => }/IUnion.cs | 0 src/Split/net47/{Union => }/UnionAttribute.cs | 0 src/Split/net471/{Union => }/IUnion.cs | 0 .../net471/{Union => }/UnionAttribute.cs | 0 src/Split/net472/{Union => }/IUnion.cs | 0 .../net472/{Union => }/UnionAttribute.cs | 0 src/Split/net48/{Union => }/IUnion.cs | 0 src/Split/net48/{Union => }/UnionAttribute.cs | 0 src/Split/net481/{Union => }/IUnion.cs | 0 .../net481/{Union => }/UnionAttribute.cs | 0 src/Split/net5.0/{Union => }/IUnion.cs | 0 .../net5.0/{Union => }/UnionAttribute.cs | 0 src/Split/net6.0/{Union => }/IUnion.cs | 0 .../net6.0/{Union => }/UnionAttribute.cs | 0 src/Split/net7.0/{Union => }/IUnion.cs | 0 .../net7.0/{Union => }/UnionAttribute.cs | 0 src/Split/net8.0/{Union => }/IUnion.cs | 0 .../net8.0/{Union => }/UnionAttribute.cs | 0 src/Split/net9.0/{Union => }/IUnion.cs | 0 .../net9.0/{Union => }/UnionAttribute.cs | 0 src/Split/netcoreapp2.0/{Union => }/IUnion.cs | 0 .../{Union => }/UnionAttribute.cs | 0 src/Split/netcoreapp2.1/{Union => }/IUnion.cs | 0 .../{Union => }/UnionAttribute.cs | 0 src/Split/netcoreapp2.2/{Union => }/IUnion.cs | 0 .../{Union => }/UnionAttribute.cs | 0 src/Split/netcoreapp3.0/{Union => }/IUnion.cs | 0 .../{Union => }/UnionAttribute.cs | 0 src/Split/netcoreapp3.1/{Union => }/IUnion.cs | 0 .../{Union => }/UnionAttribute.cs | 0 .../netstandard2.0/{Union => }/IUnion.cs | 0 .../{Union => }/UnionAttribute.cs | 0 .../netstandard2.1/{Union => }/IUnion.cs | 0 .../{Union => }/UnionAttribute.cs | 0 src/Split/uap10.0/{Union => }/IUnion.cs | 0 .../uap10.0/{Union => }/UnionAttribute.cs | 0 55 files changed, 88 insertions(+), 106 deletions(-) rename src/Polyfill/{Union => }/IUnion.cs (100%) rename src/Polyfill/{Union => }/UnionAttribute.cs (100%) rename src/Split/net10.0/{Union => }/IUnion.cs (100%) rename src/Split/net10.0/{Union => }/UnionAttribute.cs (100%) rename src/Split/net461/{Union => }/IUnion.cs (100%) rename src/Split/net461/{Union => }/UnionAttribute.cs (100%) rename src/Split/net462/{Union => }/IUnion.cs (100%) rename src/Split/net462/{Union => }/UnionAttribute.cs (100%) rename src/Split/net47/{Union => }/IUnion.cs (100%) rename src/Split/net47/{Union => }/UnionAttribute.cs (100%) rename src/Split/net471/{Union => }/IUnion.cs (100%) rename src/Split/net471/{Union => }/UnionAttribute.cs (100%) rename src/Split/net472/{Union => }/IUnion.cs (100%) rename src/Split/net472/{Union => }/UnionAttribute.cs (100%) rename src/Split/net48/{Union => }/IUnion.cs (100%) rename src/Split/net48/{Union => }/UnionAttribute.cs (100%) rename src/Split/net481/{Union => }/IUnion.cs (100%) rename src/Split/net481/{Union => }/UnionAttribute.cs (100%) rename src/Split/net5.0/{Union => }/IUnion.cs (100%) rename src/Split/net5.0/{Union => }/UnionAttribute.cs (100%) rename src/Split/net6.0/{Union => }/IUnion.cs (100%) rename src/Split/net6.0/{Union => }/UnionAttribute.cs (100%) rename src/Split/net7.0/{Union => }/IUnion.cs (100%) rename src/Split/net7.0/{Union => }/UnionAttribute.cs (100%) rename src/Split/net8.0/{Union => }/IUnion.cs (100%) rename src/Split/net8.0/{Union => }/UnionAttribute.cs (100%) rename src/Split/net9.0/{Union => }/IUnion.cs (100%) rename src/Split/net9.0/{Union => }/UnionAttribute.cs (100%) rename src/Split/netcoreapp2.0/{Union => }/IUnion.cs (100%) rename src/Split/netcoreapp2.0/{Union => }/UnionAttribute.cs (100%) rename src/Split/netcoreapp2.1/{Union => }/IUnion.cs (100%) rename src/Split/netcoreapp2.1/{Union => }/UnionAttribute.cs (100%) rename src/Split/netcoreapp2.2/{Union => }/IUnion.cs (100%) rename src/Split/netcoreapp2.2/{Union => }/UnionAttribute.cs (100%) rename src/Split/netcoreapp3.0/{Union => }/IUnion.cs (100%) rename src/Split/netcoreapp3.0/{Union => }/UnionAttribute.cs (100%) rename src/Split/netcoreapp3.1/{Union => }/IUnion.cs (100%) rename src/Split/netcoreapp3.1/{Union => }/UnionAttribute.cs (100%) rename src/Split/netstandard2.0/{Union => }/IUnion.cs (100%) rename src/Split/netstandard2.0/{Union => }/UnionAttribute.cs (100%) rename src/Split/netstandard2.1/{Union => }/IUnion.cs (100%) rename src/Split/netstandard2.1/{Union => }/UnionAttribute.cs (100%) rename src/Split/uap10.0/{Union => }/IUnion.cs (100%) rename src/Split/uap10.0/{Union => }/UnionAttribute.cs (100%) diff --git a/api_list.include.md b/api_list.include.md index d281f227..3c1a6ec2 100644 --- a/api_list.include.md +++ b/api_list.include.md @@ -1533,8 +1533,6 @@ #### IUnion -> Requires [`true`](#unions) in the consuming project. - #### StringStream #### ReadOnlyMemoryStream diff --git a/assemblySize.include.md b/assemblySize.include.md index 87d01d3b..a0a8d92e 100644 --- a/assemblySize.include.md +++ b/assemblySize.include.md @@ -2,26 +2,26 @@ | | Empty Assembly | With Polyfill | Diff | Ensure | ArgumentExceptions | StringInterpolation | Nullability | |----------------|----------------|---------------|-----------|-----------|--------------------|---------------------|-------------| -| netstandard2.0 | 8.0KB | 358.5KB | +350.5KB | +8.0KB | +6.5KB | +8.0KB | +12.5KB | -| netstandard2.1 | 8.5KB | 312.5KB | +304.0KB | +9.0KB | +6.5KB | +9.0KB | +14.0KB | -| net461 | 8.5KB | 357.5KB | +349.0KB | +7.5KB | +6.5KB | +7.5KB | +12.0KB | -| net462 | 7.0KB | 361.0KB | +354.0KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | -| net47 | 7.0KB | 360.5KB | +353.5KB | +9.5KB | +6.5KB | +9.5KB | +14.0KB | -| net471 | 8.5KB | 360.0KB | +351.5KB | +7.5KB | +6.5KB | +7.5KB | +12.0KB | -| net472 | 8.5KB | 358.5KB | +350.0KB | +7.5KB | +6.5KB | +8.0KB | +12.0KB | -| net48 | 8.5KB | 358.5KB | +350.0KB | +7.5KB | +6.5KB | +8.0KB | +12.0KB | -| net481 | 8.5KB | 358.5KB | +350.0KB | +7.5KB | +6.5KB | +8.0KB | +12.0KB | -| netcoreapp2.0 | 9.0KB | 336.0KB | +327.0KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | -| netcoreapp2.1 | 9.0KB | 316.0KB | +307.0KB | +9.0KB | +6.5KB | +9.0KB | +14.0KB | -| netcoreapp2.2 | 9.0KB | 316.0KB | +307.0KB | +9.0KB | +6.5KB | +9.5KB | +14.0KB | -| netcoreapp3.0 | 9.5KB | 309.5KB | +300.0KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | -| netcoreapp3.1 | 9.5KB | 307.5KB | +298.0KB | +9.0KB | +6.5KB | +9.0KB | +14.0KB | -| net5.0 | 9.5KB | 271.5KB | +262.0KB | +9.0KB | +6.5KB | +9.0KB | +14.0KB | -| net6.0 | 10.0KB | 213.0KB | +203.0KB | +9.5KB | +7.0KB | +512bytes | +3.5KB | -| net7.0 | 10.0KB | 175.0KB | +165.0KB | +11.5KB | +8.0KB | +512bytes | +3.0KB | -| net8.0 | 9.5KB | 145.5KB | +136.0KB | +8.0KB | | +512bytes | +3.0KB | -| net9.0 | 9.5KB | 98.5KB | +89.0KB | +8.5KB | | +512bytes | +3.0KB | -| net10.0 | 10.0KB | 76.0KB | +66.0KB | +8.5KB | | +512bytes | +3.5KB | +| netstandard2.0 | 8.0KB | 359.0KB | +351.0KB | +7.5KB | +6.5KB | +7.5KB | +12.0KB | +| netstandard2.1 | 8.5KB | 313.0KB | +304.5KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | +| net461 | 8.5KB | 357.5KB | +349.0KB | +8.0KB | +7.0KB | +8.0KB | +12.5KB | +| net462 | 7.0KB | 361.0KB | +354.0KB | +9.5KB | +6.5KB | +9.5KB | +14.0KB | +| net47 | 7.0KB | 361.0KB | +354.0KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | +| net471 | 8.5KB | 360.0KB | +351.5KB | +7.5KB | +6.5KB | +8.0KB | +12.5KB | +| net472 | 8.5KB | 358.5KB | +350.0KB | +8.0KB | +7.0KB | +8.0KB | +12.5KB | +| net48 | 8.5KB | 358.5KB | +350.0KB | +8.0KB | +7.0KB | +8.0KB | +12.5KB | +| net481 | 8.5KB | 359.0KB | +350.5KB | +7.5KB | +6.5KB | +7.5KB | +12.0KB | +| netcoreapp2.0 | 9.0KB | 336.5KB | +327.5KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | +| netcoreapp2.1 | 9.0KB | 316.5KB | +307.5KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | +| netcoreapp2.2 | 9.0KB | 316.5KB | +307.5KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | +| netcoreapp3.0 | 9.5KB | 309.5KB | +300.0KB | +9.0KB | +6.5KB | +9.0KB | +14.0KB | +| netcoreapp3.1 | 9.5KB | 308.0KB | +298.5KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | +| net5.0 | 9.5KB | 272.0KB | +262.5KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | +| net6.0 | 10.0KB | 213.0KB | +203.0KB | +10.0KB | +7.0KB | +1.0KB | +3.5KB | +| net7.0 | 10.0KB | 175.0KB | +165.0KB | +12.0KB | +8.5KB | +512bytes | +3.5KB | +| net8.0 | 9.5KB | 145.5KB | +136.0KB | +8.5KB | +512bytes | +512bytes | +3.5KB | +| net9.0 | 9.5KB | 98.5KB | +89.0KB | +8.5KB | | +512bytes | +3.5KB | +| net10.0 | 10.0KB | 76.0KB | +66.0KB | +9.0KB | | +1.0KB | +3.5KB | | net11.0 | 10.0KB | 21.0KB | +11.0KB | +9.0KB | | +512bytes | +3.5KB | @@ -29,24 +29,24 @@ | | Empty Assembly | With Polyfill | Diff | Ensure | ArgumentExceptions | StringInterpolation | Nullability | |----------------|----------------|---------------|-----------|-----------|--------------------|---------------------|-------------| -| netstandard2.0 | 8.0KB | 525.8KB | +517.8KB | +15.7KB | +8.2KB | +12.9KB | +17.9KB | -| netstandard2.1 | 8.5KB | 453.1KB | +444.6KB | +16.7KB | +8.2KB | +13.9KB | +19.4KB | -| net461 | 8.5KB | 525.8KB | +517.3KB | +15.2KB | +8.2KB | +12.4KB | +17.4KB | -| net462 | 7.0KB | 529.3KB | +522.3KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | -| net47 | 7.0KB | 528.6KB | +521.6KB | +17.2KB | +8.2KB | +14.4KB | +19.4KB | -| net471 | 8.5KB | 527.7KB | +519.2KB | +15.2KB | +8.2KB | +12.4KB | +17.4KB | -| net472 | 8.5KB | 525.1KB | +516.6KB | +15.2KB | +8.2KB | +12.9KB | +17.4KB | -| net48 | 8.5KB | 525.1KB | +516.6KB | +15.2KB | +8.2KB | +12.9KB | +17.4KB | -| net481 | 8.5KB | 525.1KB | +516.6KB | +15.2KB | +8.2KB | +12.9KB | +17.4KB | -| netcoreapp2.0 | 9.0KB | 492.7KB | +483.7KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | -| netcoreapp2.1 | 9.0KB | 460.4KB | +451.4KB | +16.7KB | +8.2KB | +13.9KB | +19.4KB | -| netcoreapp2.2 | 9.0KB | 460.4KB | +451.4KB | +16.7KB | +8.2KB | +14.4KB | +19.4KB | -| netcoreapp3.0 | 9.5KB | 445.0KB | +435.5KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | -| netcoreapp3.1 | 9.5KB | 442.9KB | +433.4KB | +16.7KB | +8.2KB | +13.9KB | +19.4KB | -| net5.0 | 9.5KB | 388.8KB | +379.3KB | +16.7KB | +8.2KB | +13.9KB | +19.4KB | -| net6.0 | 10.0KB | 310.1KB | +300.1KB | +17.2KB | +8.7KB | +1.1KB | +4.2KB | -| net7.0 | 10.0KB | 253.2KB | +243.2KB | +19.1KB | +9.4KB | +1.1KB | +3.7KB | -| net8.0 | 9.5KB | 208.2KB | +198.7KB | +15.5KB | +299bytes | +1.1KB | +3.7KB | -| net9.0 | 9.5KB | 140.1KB | +130.6KB | +16.0KB | | +1.1KB | +3.7KB | -| net10.0 | 10.0KB | 108.9KB | +98.9KB | +16.0KB | | +1.1KB | +4.2KB | +| netstandard2.0 | 8.0KB | 526.3KB | +518.3KB | +15.2KB | +8.2KB | +12.4KB | +17.4KB | +| netstandard2.1 | 8.5KB | 453.6KB | +445.1KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | +| net461 | 8.5KB | 525.8KB | +517.3KB | +15.7KB | +8.7KB | +12.9KB | +17.9KB | +| net462 | 7.0KB | 529.3KB | +522.3KB | +17.2KB | +8.2KB | +14.4KB | +19.4KB | +| net47 | 7.0KB | 529.1KB | +522.1KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | +| net471 | 8.5KB | 527.7KB | +519.2KB | +15.2KB | +8.2KB | +12.9KB | +17.9KB | +| net472 | 8.5KB | 525.1KB | +516.6KB | +15.7KB | +8.7KB | +12.9KB | +17.9KB | +| net48 | 8.5KB | 525.1KB | +516.6KB | +15.7KB | +8.7KB | +12.9KB | +17.9KB | +| net481 | 8.5KB | 525.6KB | +517.1KB | +15.2KB | +8.2KB | +12.4KB | +17.4KB | +| netcoreapp2.0 | 9.0KB | 493.2KB | +484.2KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | +| netcoreapp2.1 | 9.0KB | 460.9KB | +451.9KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | +| netcoreapp2.2 | 9.0KB | 460.9KB | +451.9KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | +| netcoreapp3.0 | 9.5KB | 445.0KB | +435.5KB | +16.7KB | +8.2KB | +13.9KB | +19.4KB | +| netcoreapp3.1 | 9.5KB | 443.4KB | +433.9KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | +| net5.0 | 9.5KB | 389.3KB | +379.8KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | +| net6.0 | 10.0KB | 310.1KB | +300.1KB | +17.7KB | +8.7KB | +1.6KB | +4.2KB | +| net7.0 | 10.0KB | 253.2KB | +243.2KB | +19.6KB | +9.9KB | +1.1KB | +4.2KB | +| net8.0 | 9.5KB | 208.2KB | +198.7KB | +16.0KB | +811bytes | +1.1KB | +4.2KB | +| net9.0 | 9.5KB | 140.1KB | +130.6KB | +16.0KB | | +1.1KB | +4.2KB | +| net10.0 | 10.0KB | 108.9KB | +98.9KB | +16.5KB | | +1.6KB | +4.2KB | | net11.0 | 10.0KB | 30.9KB | +20.9KB | +16.5KB | | +1.1KB | +4.2KB | diff --git a/readme.md b/readme.md index 4898fc86..ddf0baec 100644 --- a/readme.md +++ b/readme.md @@ -96,26 +96,26 @@ This project uses features from the newest stable SDK and C# language. As such c | | Empty Assembly | With Polyfill | Diff | Ensure | ArgumentExceptions | StringInterpolation | Nullability | |----------------|----------------|---------------|-----------|-----------|--------------------|---------------------|-------------| -| netstandard2.0 | 8.0KB | 358.5KB | +350.5KB | +8.0KB | +6.5KB | +8.0KB | +12.5KB | -| netstandard2.1 | 8.5KB | 312.5KB | +304.0KB | +9.0KB | +6.5KB | +9.0KB | +14.0KB | -| net461 | 8.5KB | 357.5KB | +349.0KB | +7.5KB | +6.5KB | +7.5KB | +12.0KB | -| net462 | 7.0KB | 361.0KB | +354.0KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | -| net47 | 7.0KB | 360.5KB | +353.5KB | +9.5KB | +6.5KB | +9.5KB | +14.0KB | -| net471 | 8.5KB | 360.0KB | +351.5KB | +7.5KB | +6.5KB | +7.5KB | +12.0KB | -| net472 | 8.5KB | 358.5KB | +350.0KB | +7.5KB | +6.5KB | +8.0KB | +12.0KB | -| net48 | 8.5KB | 358.5KB | +350.0KB | +7.5KB | +6.5KB | +8.0KB | +12.0KB | -| net481 | 8.5KB | 358.5KB | +350.0KB | +7.5KB | +6.5KB | +8.0KB | +12.0KB | -| netcoreapp2.0 | 9.0KB | 336.0KB | +327.0KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | -| netcoreapp2.1 | 9.0KB | 316.0KB | +307.0KB | +9.0KB | +6.5KB | +9.0KB | +14.0KB | -| netcoreapp2.2 | 9.0KB | 316.0KB | +307.0KB | +9.0KB | +6.5KB | +9.5KB | +14.0KB | -| netcoreapp3.0 | 9.5KB | 309.5KB | +300.0KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | -| netcoreapp3.1 | 9.5KB | 307.5KB | +298.0KB | +9.0KB | +6.5KB | +9.0KB | +14.0KB | -| net5.0 | 9.5KB | 271.5KB | +262.0KB | +9.0KB | +6.5KB | +9.0KB | +14.0KB | -| net6.0 | 10.0KB | 213.0KB | +203.0KB | +9.5KB | +7.0KB | +512bytes | +3.5KB | -| net7.0 | 10.0KB | 175.0KB | +165.0KB | +11.5KB | +8.0KB | +512bytes | +3.0KB | -| net8.0 | 9.5KB | 145.5KB | +136.0KB | +8.0KB | | +512bytes | +3.0KB | -| net9.0 | 9.5KB | 98.5KB | +89.0KB | +8.5KB | | +512bytes | +3.0KB | -| net10.0 | 10.0KB | 76.0KB | +66.0KB | +8.5KB | | +512bytes | +3.5KB | +| netstandard2.0 | 8.0KB | 359.0KB | +351.0KB | +7.5KB | +6.5KB | +7.5KB | +12.0KB | +| netstandard2.1 | 8.5KB | 313.0KB | +304.5KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | +| net461 | 8.5KB | 357.5KB | +349.0KB | +8.0KB | +7.0KB | +8.0KB | +12.5KB | +| net462 | 7.0KB | 361.0KB | +354.0KB | +9.5KB | +6.5KB | +9.5KB | +14.0KB | +| net47 | 7.0KB | 361.0KB | +354.0KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | +| net471 | 8.5KB | 360.0KB | +351.5KB | +7.5KB | +6.5KB | +8.0KB | +12.5KB | +| net472 | 8.5KB | 358.5KB | +350.0KB | +8.0KB | +7.0KB | +8.0KB | +12.5KB | +| net48 | 8.5KB | 358.5KB | +350.0KB | +8.0KB | +7.0KB | +8.0KB | +12.5KB | +| net481 | 8.5KB | 359.0KB | +350.5KB | +7.5KB | +6.5KB | +7.5KB | +12.0KB | +| netcoreapp2.0 | 9.0KB | 336.5KB | +327.5KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | +| netcoreapp2.1 | 9.0KB | 316.5KB | +307.5KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | +| netcoreapp2.2 | 9.0KB | 316.5KB | +307.5KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | +| netcoreapp3.0 | 9.5KB | 309.5KB | +300.0KB | +9.0KB | +6.5KB | +9.0KB | +14.0KB | +| netcoreapp3.1 | 9.5KB | 308.0KB | +298.5KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | +| net5.0 | 9.5KB | 272.0KB | +262.5KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | +| net6.0 | 10.0KB | 213.0KB | +203.0KB | +10.0KB | +7.0KB | +1.0KB | +3.5KB | +| net7.0 | 10.0KB | 175.0KB | +165.0KB | +12.0KB | +8.5KB | +512bytes | +3.5KB | +| net8.0 | 9.5KB | 145.5KB | +136.0KB | +8.5KB | +512bytes | +512bytes | +3.5KB | +| net9.0 | 9.5KB | 98.5KB | +89.0KB | +8.5KB | | +512bytes | +3.5KB | +| net10.0 | 10.0KB | 76.0KB | +66.0KB | +9.0KB | | +1.0KB | +3.5KB | | net11.0 | 10.0KB | 21.0KB | +11.0KB | +9.0KB | | +512bytes | +3.5KB | @@ -123,26 +123,26 @@ This project uses features from the newest stable SDK and C# language. As such c | | Empty Assembly | With Polyfill | Diff | Ensure | ArgumentExceptions | StringInterpolation | Nullability | |----------------|----------------|---------------|-----------|-----------|--------------------|---------------------|-------------| -| netstandard2.0 | 8.0KB | 525.8KB | +517.8KB | +15.7KB | +8.2KB | +12.9KB | +17.9KB | -| netstandard2.1 | 8.5KB | 453.1KB | +444.6KB | +16.7KB | +8.2KB | +13.9KB | +19.4KB | -| net461 | 8.5KB | 525.8KB | +517.3KB | +15.2KB | +8.2KB | +12.4KB | +17.4KB | -| net462 | 7.0KB | 529.3KB | +522.3KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | -| net47 | 7.0KB | 528.6KB | +521.6KB | +17.2KB | +8.2KB | +14.4KB | +19.4KB | -| net471 | 8.5KB | 527.7KB | +519.2KB | +15.2KB | +8.2KB | +12.4KB | +17.4KB | -| net472 | 8.5KB | 525.1KB | +516.6KB | +15.2KB | +8.2KB | +12.9KB | +17.4KB | -| net48 | 8.5KB | 525.1KB | +516.6KB | +15.2KB | +8.2KB | +12.9KB | +17.4KB | -| net481 | 8.5KB | 525.1KB | +516.6KB | +15.2KB | +8.2KB | +12.9KB | +17.4KB | -| netcoreapp2.0 | 9.0KB | 492.7KB | +483.7KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | -| netcoreapp2.1 | 9.0KB | 460.4KB | +451.4KB | +16.7KB | +8.2KB | +13.9KB | +19.4KB | -| netcoreapp2.2 | 9.0KB | 460.4KB | +451.4KB | +16.7KB | +8.2KB | +14.4KB | +19.4KB | -| netcoreapp3.0 | 9.5KB | 445.0KB | +435.5KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | -| netcoreapp3.1 | 9.5KB | 442.9KB | +433.4KB | +16.7KB | +8.2KB | +13.9KB | +19.4KB | -| net5.0 | 9.5KB | 388.8KB | +379.3KB | +16.7KB | +8.2KB | +13.9KB | +19.4KB | -| net6.0 | 10.0KB | 310.1KB | +300.1KB | +17.2KB | +8.7KB | +1.1KB | +4.2KB | -| net7.0 | 10.0KB | 253.2KB | +243.2KB | +19.1KB | +9.4KB | +1.1KB | +3.7KB | -| net8.0 | 9.5KB | 208.2KB | +198.7KB | +15.5KB | +299bytes | +1.1KB | +3.7KB | -| net9.0 | 9.5KB | 140.1KB | +130.6KB | +16.0KB | | +1.1KB | +3.7KB | -| net10.0 | 10.0KB | 108.9KB | +98.9KB | +16.0KB | | +1.1KB | +4.2KB | +| netstandard2.0 | 8.0KB | 526.3KB | +518.3KB | +15.2KB | +8.2KB | +12.4KB | +17.4KB | +| netstandard2.1 | 8.5KB | 453.6KB | +445.1KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | +| net461 | 8.5KB | 525.8KB | +517.3KB | +15.7KB | +8.7KB | +12.9KB | +17.9KB | +| net462 | 7.0KB | 529.3KB | +522.3KB | +17.2KB | +8.2KB | +14.4KB | +19.4KB | +| net47 | 7.0KB | 529.1KB | +522.1KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | +| net471 | 8.5KB | 527.7KB | +519.2KB | +15.2KB | +8.2KB | +12.9KB | +17.9KB | +| net472 | 8.5KB | 525.1KB | +516.6KB | +15.7KB | +8.7KB | +12.9KB | +17.9KB | +| net48 | 8.5KB | 525.1KB | +516.6KB | +15.7KB | +8.7KB | +12.9KB | +17.9KB | +| net481 | 8.5KB | 525.6KB | +517.1KB | +15.2KB | +8.2KB | +12.4KB | +17.4KB | +| netcoreapp2.0 | 9.0KB | 493.2KB | +484.2KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | +| netcoreapp2.1 | 9.0KB | 460.9KB | +451.9KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | +| netcoreapp2.2 | 9.0KB | 460.9KB | +451.9KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | +| netcoreapp3.0 | 9.5KB | 445.0KB | +435.5KB | +16.7KB | +8.2KB | +13.9KB | +19.4KB | +| netcoreapp3.1 | 9.5KB | 443.4KB | +433.9KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | +| net5.0 | 9.5KB | 389.3KB | +379.8KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | +| net6.0 | 10.0KB | 310.1KB | +300.1KB | +17.7KB | +8.7KB | +1.6KB | +4.2KB | +| net7.0 | 10.0KB | 253.2KB | +243.2KB | +19.6KB | +9.9KB | +1.1KB | +4.2KB | +| net8.0 | 9.5KB | 208.2KB | +198.7KB | +16.0KB | +811bytes | +1.1KB | +4.2KB | +| net9.0 | 9.5KB | 140.1KB | +130.6KB | +16.0KB | | +1.1KB | +4.2KB | +| net10.0 | 10.0KB | 108.9KB | +98.9KB | +16.5KB | | +1.6KB | +4.2KB | | net11.0 | 10.0KB | 30.9KB | +20.9KB | +16.5KB | | +1.1KB | +4.2KB | @@ -531,16 +531,11 @@ Polyfills the two marker types that the compiler references when emitting [C# 15 * [UnionAttribute](https://learn.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.unionattribute) * [IUnion](https://learn.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.iunion) -This is opt-in. It is off by default to avoid clashing with the `UnionAttribute`/`IUnion` that current preview guidance has projects declare themselves. Enable it in the consuming project: +Both types ship in net11. Without them the compiler rejects a `union` declaration with `CS0518` and `CS0656`, so Polyfill supplies them on every earlier target. -```xml - - true - preview - -``` +> Polyfill supplies only the `UnionAttribute` and `IUnion` types that the generated union struct references. The `union` keyword itself requires the C# 15 (or later) compiler and cannot be backported to an older compiler. Set `preview` while the feature is in preview. -> Polyfill supplies only the `UnionAttribute` and `IUnion` types that the generated union struct references. The `union` keyword itself requires the C# 15 (or later) compiler and cannot be backported to an older compiler. +> If the consuming project declares its own `UnionAttribute`/`IUnion` in `System.Runtime.CompilerServices` (as preview guidance suggested before these types shipped), delete those declarations. Keeping them results in `CS0101` on earlier targets and `CS0729` on net11. Declaring a union: @@ -2153,8 +2148,6 @@ The class `Polyfill` includes the following extension methods: #### IUnion -> Requires [`true`](#unions) in the consuming project. - #### StringStream #### ReadOnlyMemoryStream @@ -2360,7 +2353,7 @@ void ObjectDisposedExceptionExample(bool isDisposed) ObjectDisposedException.ThrowIf(isDisposed, typeof(Consume)); } ``` -snippet source | anchor +snippet source | anchor @@ -2379,7 +2372,7 @@ void EnsureExample(Order order, Customer customer, string customerId, string ema this.quantity = Ensure.NotNegativeOrZero(quantity); } ``` -snippet source | anchor +snippet source | anchor diff --git a/src/ApiBuilderTests/BuildApiTest.cs b/src/ApiBuilderTests/BuildApiTest.cs index a348eea9..b5ab6928 100644 --- a/src/ApiBuilderTests/BuildApiTest.cs +++ b/src/ApiBuilderTests/BuildApiTest.cs @@ -313,7 +313,6 @@ static void WriteTypeMethods(string name, StreamWriter writer, ref int count, IE ["ArgumentOutOfRangeException"] = ("PolyArgumentExceptions", "argumentexception-1"), ["ObjectDisposedException"] = ("PolyArgumentExceptions", "argumentexception-1"), ["Ensure"] = ("PolyEnsure", "ensure-1"), - ["IUnion"] = ("PolyUnion", "unions"), }; static void WriteSectionGate(string sectionName, StreamWriter writer) diff --git a/src/Consume/Consume.cs b/src/Consume/Consume.cs index 7d997562..8e9a5870 100644 --- a/src/Consume/Consume.cs +++ b/src/Consume/Consume.cs @@ -104,10 +104,8 @@ class Consume type = typeof(RequiresUnreferencedCodeAttribute); type = typeof(UnconditionalSuppressMessageAttribute); type = typeof(CompilerFeatureRequiredAttribute); -#if PolyUnion type = typeof(IUnion); type = typeof(UnionAttribute); -#endif #if FeatureMemory type = typeof(CollectionBuilderAttribute); #endif diff --git a/src/Consume/Consume.csproj b/src/Consume/Consume.csproj index 0e456852..9b4e448b 100644 --- a/src/Consume/Consume.csproj +++ b/src/Consume/Consume.csproj @@ -2,7 +2,7 @@ $(NoWarn);PolyfillTargetsForNuget true - $(DefineConstants);PolyEnsure;PolyArgumentExceptions;PolyUnion + $(DefineConstants);PolyEnsure;PolyArgumentExceptions net461;net462;net47;net471;net472;net48;net481;net6.0-windows;netstandard2.0;netstandard2.1;netcoreapp2.0;netcoreapp2.1;netcoreapp2.2;netcoreapp3.0;netcoreapp3.1;net5.0;net6.0;net7.0;net8.0;net9.0;net10.0;net11.0 net481;netcoreapp3.1;net10.0;net11.0 diff --git a/src/ConsumeNoOptional/ConsumeNoOptional.csproj b/src/ConsumeNoOptional/ConsumeNoOptional.csproj index dcb8a078..8e72689a 100644 --- a/src/ConsumeNoOptional/ConsumeNoOptional.csproj +++ b/src/ConsumeNoOptional/ConsumeNoOptional.csproj @@ -9,7 +9,6 @@ false false false - false $(DefineConstants);NoStringInterpolation diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 536b26e4..46d939dc 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -19,7 +19,6 @@ true true true - true true false enable diff --git a/src/NoExtrasTests/NoExtrasTests.csproj b/src/NoExtrasTests/NoExtrasTests.csproj index fdbedc32..293d3698 100644 --- a/src/NoExtrasTests/NoExtrasTests.csproj +++ b/src/NoExtrasTests/NoExtrasTests.csproj @@ -8,7 +8,6 @@ false false false - false NoExtras diff --git a/src/Polyfill/Union/IUnion.cs b/src/Polyfill/IUnion.cs similarity index 100% rename from src/Polyfill/Union/IUnion.cs rename to src/Polyfill/IUnion.cs diff --git a/src/Polyfill/Polyfill.targets b/src/Polyfill/Polyfill.targets index c0264d92..88118b8a 100644 --- a/src/Polyfill/Polyfill.targets +++ b/src/Polyfill/Polyfill.targets @@ -166,9 +166,6 @@ For example: - - false diff --git a/src/Polyfill/Union/UnionAttribute.cs b/src/Polyfill/UnionAttribute.cs similarity index 100% rename from src/Polyfill/Union/UnionAttribute.cs rename to src/Polyfill/UnionAttribute.cs diff --git a/src/Split/net10.0/Union/IUnion.cs b/src/Split/net10.0/IUnion.cs similarity index 100% rename from src/Split/net10.0/Union/IUnion.cs rename to src/Split/net10.0/IUnion.cs diff --git a/src/Split/net10.0/Union/UnionAttribute.cs b/src/Split/net10.0/UnionAttribute.cs similarity index 100% rename from src/Split/net10.0/Union/UnionAttribute.cs rename to src/Split/net10.0/UnionAttribute.cs diff --git a/src/Split/net11.0/TypeForwardeds.cs b/src/Split/net11.0/TypeForwardeds.cs index 139e6e91..5b038c2e 100644 --- a/src/Split/net11.0/TypeForwardeds.cs +++ b/src/Split/net11.0/TypeForwardeds.cs @@ -20,6 +20,7 @@ [assembly: TypeForwardedTo(typeof(System.Collections.Generic.IAlternateEqualityComparer<,>))] [assembly: TypeForwardedTo(typeof(System.Runtime.CompilerServices.IsClosedTypeAttribute))] [assembly: TypeForwardedTo(typeof(System.Runtime.CompilerServices.IsExternalInit))] +[assembly: TypeForwardedTo(typeof(System.Runtime.CompilerServices.IUnion))] [assembly: TypeForwardedTo(typeof(System.Collections.Generic.KeyValuePair))] [assembly: TypeForwardedTo(typeof(System.Threading.Lock))] [assembly: TypeForwardedTo(typeof(System.IO.MatchCasing))] @@ -44,6 +45,7 @@ [assembly: TypeForwardedTo(typeof(System.IO.StringStream))] [assembly: TypeForwardedTo(typeof(System.Diagnostics.CodeAnalysis.StringSyntaxAttribute))] [assembly: TypeForwardedTo(typeof(System.Runtime.InteropServices.SuppressGCTransitionAttribute))] +[assembly: TypeForwardedTo(typeof(System.Runtime.CompilerServices.UnionAttribute))] [assembly: TypeForwardedTo(typeof(System.IO.UnixFileMode))] [assembly: TypeForwardedTo(typeof(System.Runtime.InteropServices.UnmanagedCallersOnlyAttribute))] [assembly: TypeForwardedTo(typeof(System.Diagnostics.UnreachableException))] @@ -84,5 +86,3 @@ [assembly: TypeForwardedTo(typeof(System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute))] [assembly: TypeForwardedTo(typeof(System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute))] [assembly: TypeForwardedTo(typeof(System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessageAttribute))] -[assembly: TypeForwardedTo(typeof(System.Runtime.CompilerServices.IUnion))] -[assembly: TypeForwardedTo(typeof(System.Runtime.CompilerServices.UnionAttribute))] diff --git a/src/Split/net461/Union/IUnion.cs b/src/Split/net461/IUnion.cs similarity index 100% rename from src/Split/net461/Union/IUnion.cs rename to src/Split/net461/IUnion.cs diff --git a/src/Split/net461/Union/UnionAttribute.cs b/src/Split/net461/UnionAttribute.cs similarity index 100% rename from src/Split/net461/Union/UnionAttribute.cs rename to src/Split/net461/UnionAttribute.cs diff --git a/src/Split/net462/Union/IUnion.cs b/src/Split/net462/IUnion.cs similarity index 100% rename from src/Split/net462/Union/IUnion.cs rename to src/Split/net462/IUnion.cs diff --git a/src/Split/net462/Union/UnionAttribute.cs b/src/Split/net462/UnionAttribute.cs similarity index 100% rename from src/Split/net462/Union/UnionAttribute.cs rename to src/Split/net462/UnionAttribute.cs diff --git a/src/Split/net47/Union/IUnion.cs b/src/Split/net47/IUnion.cs similarity index 100% rename from src/Split/net47/Union/IUnion.cs rename to src/Split/net47/IUnion.cs diff --git a/src/Split/net47/Union/UnionAttribute.cs b/src/Split/net47/UnionAttribute.cs similarity index 100% rename from src/Split/net47/Union/UnionAttribute.cs rename to src/Split/net47/UnionAttribute.cs diff --git a/src/Split/net471/Union/IUnion.cs b/src/Split/net471/IUnion.cs similarity index 100% rename from src/Split/net471/Union/IUnion.cs rename to src/Split/net471/IUnion.cs diff --git a/src/Split/net471/Union/UnionAttribute.cs b/src/Split/net471/UnionAttribute.cs similarity index 100% rename from src/Split/net471/Union/UnionAttribute.cs rename to src/Split/net471/UnionAttribute.cs diff --git a/src/Split/net472/Union/IUnion.cs b/src/Split/net472/IUnion.cs similarity index 100% rename from src/Split/net472/Union/IUnion.cs rename to src/Split/net472/IUnion.cs diff --git a/src/Split/net472/Union/UnionAttribute.cs b/src/Split/net472/UnionAttribute.cs similarity index 100% rename from src/Split/net472/Union/UnionAttribute.cs rename to src/Split/net472/UnionAttribute.cs diff --git a/src/Split/net48/Union/IUnion.cs b/src/Split/net48/IUnion.cs similarity index 100% rename from src/Split/net48/Union/IUnion.cs rename to src/Split/net48/IUnion.cs diff --git a/src/Split/net48/Union/UnionAttribute.cs b/src/Split/net48/UnionAttribute.cs similarity index 100% rename from src/Split/net48/Union/UnionAttribute.cs rename to src/Split/net48/UnionAttribute.cs diff --git a/src/Split/net481/Union/IUnion.cs b/src/Split/net481/IUnion.cs similarity index 100% rename from src/Split/net481/Union/IUnion.cs rename to src/Split/net481/IUnion.cs diff --git a/src/Split/net481/Union/UnionAttribute.cs b/src/Split/net481/UnionAttribute.cs similarity index 100% rename from src/Split/net481/Union/UnionAttribute.cs rename to src/Split/net481/UnionAttribute.cs diff --git a/src/Split/net5.0/Union/IUnion.cs b/src/Split/net5.0/IUnion.cs similarity index 100% rename from src/Split/net5.0/Union/IUnion.cs rename to src/Split/net5.0/IUnion.cs diff --git a/src/Split/net5.0/Union/UnionAttribute.cs b/src/Split/net5.0/UnionAttribute.cs similarity index 100% rename from src/Split/net5.0/Union/UnionAttribute.cs rename to src/Split/net5.0/UnionAttribute.cs diff --git a/src/Split/net6.0/Union/IUnion.cs b/src/Split/net6.0/IUnion.cs similarity index 100% rename from src/Split/net6.0/Union/IUnion.cs rename to src/Split/net6.0/IUnion.cs diff --git a/src/Split/net6.0/Union/UnionAttribute.cs b/src/Split/net6.0/UnionAttribute.cs similarity index 100% rename from src/Split/net6.0/Union/UnionAttribute.cs rename to src/Split/net6.0/UnionAttribute.cs diff --git a/src/Split/net7.0/Union/IUnion.cs b/src/Split/net7.0/IUnion.cs similarity index 100% rename from src/Split/net7.0/Union/IUnion.cs rename to src/Split/net7.0/IUnion.cs diff --git a/src/Split/net7.0/Union/UnionAttribute.cs b/src/Split/net7.0/UnionAttribute.cs similarity index 100% rename from src/Split/net7.0/Union/UnionAttribute.cs rename to src/Split/net7.0/UnionAttribute.cs diff --git a/src/Split/net8.0/Union/IUnion.cs b/src/Split/net8.0/IUnion.cs similarity index 100% rename from src/Split/net8.0/Union/IUnion.cs rename to src/Split/net8.0/IUnion.cs diff --git a/src/Split/net8.0/Union/UnionAttribute.cs b/src/Split/net8.0/UnionAttribute.cs similarity index 100% rename from src/Split/net8.0/Union/UnionAttribute.cs rename to src/Split/net8.0/UnionAttribute.cs diff --git a/src/Split/net9.0/Union/IUnion.cs b/src/Split/net9.0/IUnion.cs similarity index 100% rename from src/Split/net9.0/Union/IUnion.cs rename to src/Split/net9.0/IUnion.cs diff --git a/src/Split/net9.0/Union/UnionAttribute.cs b/src/Split/net9.0/UnionAttribute.cs similarity index 100% rename from src/Split/net9.0/Union/UnionAttribute.cs rename to src/Split/net9.0/UnionAttribute.cs diff --git a/src/Split/netcoreapp2.0/Union/IUnion.cs b/src/Split/netcoreapp2.0/IUnion.cs similarity index 100% rename from src/Split/netcoreapp2.0/Union/IUnion.cs rename to src/Split/netcoreapp2.0/IUnion.cs diff --git a/src/Split/netcoreapp2.0/Union/UnionAttribute.cs b/src/Split/netcoreapp2.0/UnionAttribute.cs similarity index 100% rename from src/Split/netcoreapp2.0/Union/UnionAttribute.cs rename to src/Split/netcoreapp2.0/UnionAttribute.cs diff --git a/src/Split/netcoreapp2.1/Union/IUnion.cs b/src/Split/netcoreapp2.1/IUnion.cs similarity index 100% rename from src/Split/netcoreapp2.1/Union/IUnion.cs rename to src/Split/netcoreapp2.1/IUnion.cs diff --git a/src/Split/netcoreapp2.1/Union/UnionAttribute.cs b/src/Split/netcoreapp2.1/UnionAttribute.cs similarity index 100% rename from src/Split/netcoreapp2.1/Union/UnionAttribute.cs rename to src/Split/netcoreapp2.1/UnionAttribute.cs diff --git a/src/Split/netcoreapp2.2/Union/IUnion.cs b/src/Split/netcoreapp2.2/IUnion.cs similarity index 100% rename from src/Split/netcoreapp2.2/Union/IUnion.cs rename to src/Split/netcoreapp2.2/IUnion.cs diff --git a/src/Split/netcoreapp2.2/Union/UnionAttribute.cs b/src/Split/netcoreapp2.2/UnionAttribute.cs similarity index 100% rename from src/Split/netcoreapp2.2/Union/UnionAttribute.cs rename to src/Split/netcoreapp2.2/UnionAttribute.cs diff --git a/src/Split/netcoreapp3.0/Union/IUnion.cs b/src/Split/netcoreapp3.0/IUnion.cs similarity index 100% rename from src/Split/netcoreapp3.0/Union/IUnion.cs rename to src/Split/netcoreapp3.0/IUnion.cs diff --git a/src/Split/netcoreapp3.0/Union/UnionAttribute.cs b/src/Split/netcoreapp3.0/UnionAttribute.cs similarity index 100% rename from src/Split/netcoreapp3.0/Union/UnionAttribute.cs rename to src/Split/netcoreapp3.0/UnionAttribute.cs diff --git a/src/Split/netcoreapp3.1/Union/IUnion.cs b/src/Split/netcoreapp3.1/IUnion.cs similarity index 100% rename from src/Split/netcoreapp3.1/Union/IUnion.cs rename to src/Split/netcoreapp3.1/IUnion.cs diff --git a/src/Split/netcoreapp3.1/Union/UnionAttribute.cs b/src/Split/netcoreapp3.1/UnionAttribute.cs similarity index 100% rename from src/Split/netcoreapp3.1/Union/UnionAttribute.cs rename to src/Split/netcoreapp3.1/UnionAttribute.cs diff --git a/src/Split/netstandard2.0/Union/IUnion.cs b/src/Split/netstandard2.0/IUnion.cs similarity index 100% rename from src/Split/netstandard2.0/Union/IUnion.cs rename to src/Split/netstandard2.0/IUnion.cs diff --git a/src/Split/netstandard2.0/Union/UnionAttribute.cs b/src/Split/netstandard2.0/UnionAttribute.cs similarity index 100% rename from src/Split/netstandard2.0/Union/UnionAttribute.cs rename to src/Split/netstandard2.0/UnionAttribute.cs diff --git a/src/Split/netstandard2.1/Union/IUnion.cs b/src/Split/netstandard2.1/IUnion.cs similarity index 100% rename from src/Split/netstandard2.1/Union/IUnion.cs rename to src/Split/netstandard2.1/IUnion.cs diff --git a/src/Split/netstandard2.1/Union/UnionAttribute.cs b/src/Split/netstandard2.1/UnionAttribute.cs similarity index 100% rename from src/Split/netstandard2.1/Union/UnionAttribute.cs rename to src/Split/netstandard2.1/UnionAttribute.cs diff --git a/src/Split/uap10.0/Union/IUnion.cs b/src/Split/uap10.0/IUnion.cs similarity index 100% rename from src/Split/uap10.0/Union/IUnion.cs rename to src/Split/uap10.0/IUnion.cs diff --git a/src/Split/uap10.0/Union/UnionAttribute.cs b/src/Split/uap10.0/UnionAttribute.cs similarity index 100% rename from src/Split/uap10.0/Union/UnionAttribute.cs rename to src/Split/uap10.0/UnionAttribute.cs