From 2a438f0e14cebd2f1b54ed090c91ed482a0307ba Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Mon, 7 Sep 2026 13:53:50 +1000 Subject: [PATCH 1/4] closed hierarchy --- apiCount.include.md | 44 +++--- assemblySize.include.md | 84 +++++------ readme.md | 132 +++++++++--------- src/Consume/Consume.cs | 1 + src/Polyfill/IsClosedTypeAttribute.cs | 40 ++++++ src/Split/net10.0/IsClosedTypeAttribute.cs | 32 +++++ src/Split/net11.0/TypeForwardeds.cs | 1 + src/Split/net461/IsClosedTypeAttribute.cs | 32 +++++ src/Split/net462/IsClosedTypeAttribute.cs | 32 +++++ src/Split/net47/IsClosedTypeAttribute.cs | 32 +++++ src/Split/net471/IsClosedTypeAttribute.cs | 32 +++++ src/Split/net472/IsClosedTypeAttribute.cs | 32 +++++ src/Split/net48/IsClosedTypeAttribute.cs | 32 +++++ src/Split/net481/IsClosedTypeAttribute.cs | 32 +++++ src/Split/net5.0/IsClosedTypeAttribute.cs | 32 +++++ src/Split/net6.0/IsClosedTypeAttribute.cs | 32 +++++ src/Split/net7.0/IsClosedTypeAttribute.cs | 32 +++++ src/Split/net8.0/IsClosedTypeAttribute.cs | 32 +++++ src/Split/net9.0/IsClosedTypeAttribute.cs | 32 +++++ .../netcoreapp2.0/IsClosedTypeAttribute.cs | 32 +++++ .../netcoreapp2.1/IsClosedTypeAttribute.cs | 32 +++++ .../netcoreapp2.2/IsClosedTypeAttribute.cs | 32 +++++ .../netcoreapp3.0/IsClosedTypeAttribute.cs | 32 +++++ .../netcoreapp3.1/IsClosedTypeAttribute.cs | 32 +++++ .../netstandard2.0/IsClosedTypeAttribute.cs | 32 +++++ .../netstandard2.1/IsClosedTypeAttribute.cs | 32 +++++ src/Split/uap10.0/IsClosedTypeAttribute.cs | 32 +++++ 27 files changed, 844 insertions(+), 130 deletions(-) create mode 100644 src/Polyfill/IsClosedTypeAttribute.cs create mode 100644 src/Split/net10.0/IsClosedTypeAttribute.cs create mode 100644 src/Split/net461/IsClosedTypeAttribute.cs create mode 100644 src/Split/net462/IsClosedTypeAttribute.cs create mode 100644 src/Split/net47/IsClosedTypeAttribute.cs create mode 100644 src/Split/net471/IsClosedTypeAttribute.cs create mode 100644 src/Split/net472/IsClosedTypeAttribute.cs create mode 100644 src/Split/net48/IsClosedTypeAttribute.cs create mode 100644 src/Split/net481/IsClosedTypeAttribute.cs create mode 100644 src/Split/net5.0/IsClosedTypeAttribute.cs create mode 100644 src/Split/net6.0/IsClosedTypeAttribute.cs create mode 100644 src/Split/net7.0/IsClosedTypeAttribute.cs create mode 100644 src/Split/net8.0/IsClosedTypeAttribute.cs create mode 100644 src/Split/net9.0/IsClosedTypeAttribute.cs create mode 100644 src/Split/netcoreapp2.0/IsClosedTypeAttribute.cs create mode 100644 src/Split/netcoreapp2.1/IsClosedTypeAttribute.cs create mode 100644 src/Split/netcoreapp2.2/IsClosedTypeAttribute.cs create mode 100644 src/Split/netcoreapp3.0/IsClosedTypeAttribute.cs create mode 100644 src/Split/netcoreapp3.1/IsClosedTypeAttribute.cs create mode 100644 src/Split/netstandard2.0/IsClosedTypeAttribute.cs create mode 100644 src/Split/netstandard2.1/IsClosedTypeAttribute.cs create mode 100644 src/Split/uap10.0/IsClosedTypeAttribute.cs diff --git a/apiCount.include.md b/apiCount.include.md index 41ee45b3..1d791631 100644 --- a/apiCount.include.md +++ b/apiCount.include.md @@ -1,28 +1,28 @@ -**API count: 1031** +**API count: 1032** ### Per Target Framework | Target | APIs | | -- | -- | -| `net461` | 972 | -| `net462` | 972 | -| `net47` | 971 | -| `net471` | 970 | -| `net472` | 966 | -| `net48` | 966 | -| `net481` | 966 | -| `netstandard2.0` | 968 | -| `netstandard2.1` | 821 | -| `netcoreapp2.0` | 891 | -| `netcoreapp2.1` | 832 | -| `netcoreapp2.2` | 832 | -| `netcoreapp3.0` | 779 | -| `netcoreapp3.1` | 778 | -| `net5.0` | 650 | -| `net6.0` | 555 | -| `net7.0` | 402 | -| `net8.0` | 283 | -| `net9.0` | 189 | -| `net10.0` | 135 | +| `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 | | `net11.0` | 58 | -| `uap10.0` | 958 | +| `uap10.0` | 960 | diff --git a/assemblySize.include.md b/assemblySize.include.md index dd4f2db9..232d8d2d 100644 --- a/assemblySize.include.md +++ b/assemblySize.include.md @@ -2,51 +2,51 @@ | | Empty Assembly | With Polyfill | Diff | Ensure | ArgumentExceptions | StringInterpolation | Nullability | |----------------|----------------|---------------|-----------|-----------|--------------------|---------------------|-------------| -| netstandard2.0 | 8.0KB | 358.5KB | +350.5KB | +7.5KB | +6.5KB | +7.5KB | +12.0KB | -| netstandard2.1 | 8.5KB | 312.5KB | +304.0KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | -| net461 | 8.5KB | 357.0KB | +348.5KB | +7.5KB | +6.5KB | +8.0KB | +12.5KB | -| net462 | 7.0KB | 360.5KB | +353.5KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | -| net47 | 7.0KB | 360.5KB | +353.5KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | -| net471 | 8.5KB | 359.5KB | +351.0KB | +7.5KB | +6.5KB | +7.5KB | +12.0KB | -| net472 | 8.5KB | 358.0KB | +349.5KB | +8.0KB | +6.5KB | +8.0KB | +12.5KB | -| net48 | 8.5KB | 358.0KB | +349.5KB | +8.0KB | +6.5KB | +8.0KB | +12.5KB | -| net481 | 8.5KB | 358.0KB | +349.5KB | +8.0KB | +6.5KB | +8.0KB | +12.5KB | -| netcoreapp2.0 | 9.0KB | 336.0KB | +327.0KB | +8.5KB | +6.5KB | +9.0KB | +13.5KB | -| netcoreapp2.1 | 9.0KB | 316.0KB | +307.0KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | -| netcoreapp2.2 | 9.0KB | 316.0KB | +307.0KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | -| netcoreapp3.0 | 9.5KB | 308.5KB | +299.0KB | +9.0KB | +6.5KB | +9.0KB | +14.0KB | -| netcoreapp3.1 | 9.5KB | 307.0KB | +297.5KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | -| net5.0 | 9.5KB | 271.0KB | +261.5KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | -| net6.0 | 10.0KB | 212.5KB | +202.5KB | +10.0KB | +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 | -| net10.0 | 10.0KB | 76.0KB | +66.0KB | +8.5KB | | +512bytes | +3.5KB | -| net11.0 | 10.0KB | 20.5KB | +10.5KB | +9.0KB | | +512bytes | +3.5KB | +| netstandard2.0 | 8.0KB | 359.0KB | +351.0KB | +7.5KB | +6.5KB | +8.0KB | +12.5KB | +| netstandard2.1 | 8.5KB | 313.0KB | +304.5KB | +9.0KB | +6.5KB | +9.0KB | +14.0KB | +| net461 | 8.5KB | 358.0KB | +349.5KB | +7.5KB | +6.5KB | +7.5KB | +12.0KB | +| net462 | 7.0KB | 361.5KB | +354.5KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | +| net47 | 7.0KB | 361.0KB | +354.0KB | +9.0KB | +6.5KB | +9.5KB | +14.0KB | +| net471 | 8.5KB | 360.5KB | +352.0KB | +7.5KB | +6.5KB | +7.5KB | +12.0KB | +| net472 | 8.5KB | 359.0KB | +350.5KB | +7.5KB | +6.5KB | +7.5KB | +12.0KB | +| net48 | 8.5KB | 359.0KB | +350.5KB | +7.5KB | +6.5KB | +7.5KB | +12.0KB | +| 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 | +14.0KB | +| netcoreapp2.2 | 9.0KB | 316.5KB | +307.5KB | +9.0KB | +6.5KB | +9.0KB | +14.0KB | +| netcoreapp3.0 | 9.5KB | 310.0KB | +300.5KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | +| netcoreapp3.1 | 9.5KB | 308.0KB | +298.5KB | +9.0KB | +6.5KB | +9.0KB | +14.0KB | +| net5.0 | 9.5KB | 272.0KB | +262.5KB | +9.0KB | +6.5KB | +9.0KB | +14.0KB | +| net6.0 | 10.0KB | 213.5KB | +203.5KB | +9.5KB | +6.5KB | +512bytes | +3.0KB | +| net7.0 | 10.0KB | 175.5KB | +165.5KB | +11.5KB | +8.0KB | +512bytes | +3.0KB | +| net8.0 | 9.5KB | 145.5KB | +136.0KB | +8.5KB | +512bytes | +1.0KB | +3.5KB | +| net9.0 | 9.5KB | 99.0KB | +89.5KB | +8.0KB | | +512bytes | +3.0KB | +| net10.0 | 10.0KB | 76.5KB | +66.5KB | +8.5KB | | +512bytes | +3.5KB | +| net11.0 | 10.0KB | 20.5KB | +10.5KB | +9.0KB | | +1.0KB | +4.0KB | ### Assembly Sizes with EmbedUntrackedSources | | Empty Assembly | With Polyfill | Diff | Ensure | ArgumentExceptions | StringInterpolation | Nullability | |----------------|----------------|---------------|-----------|-----------|--------------------|---------------------|-------------| -| netstandard2.0 | 8.0KB | 524.4KB | +516.4KB | +15.2KB | +8.2KB | +12.4KB | +17.4KB | -| netstandard2.1 | 8.5KB | 451.8KB | +443.3KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | -| net461 | 8.5KB | 524.0KB | +515.5KB | +15.2KB | +8.2KB | +12.9KB | +17.9KB | -| net462 | 7.0KB | 527.5KB | +520.5KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | -| net47 | 7.0KB | 527.2KB | +520.2KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | -| net471 | 8.5KB | 525.8KB | +517.3KB | +15.2KB | +8.2KB | +12.4KB | +17.4KB | -| net472 | 8.5KB | 523.3KB | +514.8KB | +15.7KB | +8.2KB | +12.9KB | +17.9KB | -| net48 | 8.5KB | 523.3KB | +514.8KB | +15.7KB | +8.2KB | +12.9KB | +17.9KB | -| net481 | 8.5KB | 523.3KB | +514.8KB | +15.7KB | +8.2KB | +12.9KB | +17.9KB | -| netcoreapp2.0 | 9.0KB | 491.3KB | +482.3KB | +16.2KB | +8.2KB | +13.9KB | +18.9KB | -| netcoreapp2.1 | 9.0KB | 459.0KB | +450.0KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | -| netcoreapp2.2 | 9.0KB | 459.0KB | +450.0KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | -| netcoreapp3.0 | 9.5KB | 442.7KB | +433.2KB | +16.7KB | +8.2KB | +13.9KB | +19.4KB | -| netcoreapp3.1 | 9.5KB | 441.2KB | +431.7KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | -| net5.0 | 9.5KB | 387.0KB | +377.5KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | -| net6.0 | 10.0KB | 308.4KB | +298.4KB | +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.3KB | +20.3KB | +16.5KB | | +1.1KB | +4.2KB | +| netstandard2.0 | 8.0KB | 525.8KB | +517.8KB | +15.2KB | +8.2KB | +12.9KB | +17.9KB | +| netstandard2.1 | 8.5KB | 453.2KB | +444.7KB | +16.7KB | +8.2KB | +13.9KB | +19.4KB | +| net461 | 8.5KB | 525.9KB | +517.4KB | +15.2KB | +8.2KB | +12.4KB | +17.4KB | +| net462 | 7.0KB | 529.4KB | +522.4KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | +| net47 | 7.0KB | 528.6KB | +521.6KB | +16.7KB | +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.2KB | +516.7KB | +15.2KB | +8.2KB | +12.4KB | +17.4KB | +| net48 | 8.5KB | 525.2KB | +516.7KB | +15.2KB | +8.2KB | +12.4KB | +17.4KB | +| net481 | 8.5KB | 525.2KB | +516.7KB | +15.2KB | +8.2KB | +12.4KB | +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 | +13.9KB | +19.4KB | +| netcoreapp3.0 | 9.5KB | 445.0KB | +435.5KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | +| netcoreapp3.1 | 9.5KB | 443.0KB | +433.5KB | +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.2KB | +1.1KB | +3.7KB | +| net7.0 | 10.0KB | 253.2KB | +243.2KB | +19.1KB | +9.4KB | +1.1KB | +3.7KB | +| net8.0 | 9.5KB | 207.7KB | +198.2KB | +16.0KB | +811bytes | +1.6KB | +4.2KB | +| net9.0 | 9.5KB | 140.1KB | +130.6KB | +15.5KB | | +1.1KB | +3.7KB | +| net10.0 | 10.0KB | 108.9KB | +98.9KB | +16.0KB | | +1.1KB | +4.2KB | +| net11.0 | 10.0KB | 30.4KB | +20.4KB | +16.5KB | | +1.6KB | +4.7KB | diff --git a/readme.md b/readme.md index 828151bb..e536bfd7 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: 1032** ### Per Target Framework | Target | APIs | | -- | -- | -| `net461` | 972 | -| `net462` | 972 | -| `net47` | 971 | -| `net471` | 970 | -| `net472` | 966 | -| `net48` | 966 | -| `net481` | 966 | -| `netstandard2.0` | 968 | -| `netstandard2.1` | 821 | -| `netcoreapp2.0` | 891 | -| `netcoreapp2.1` | 832 | -| `netcoreapp2.2` | 832 | -| `netcoreapp3.0` | 779 | -| `netcoreapp3.1` | 778 | -| `net5.0` | 650 | -| `net6.0` | 555 | -| `net7.0` | 402 | -| `net8.0` | 283 | -| `net9.0` | 189 | -| `net10.0` | 135 | +| `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 | | `net11.0` | 58 | -| `uap10.0` | 958 | +| `uap10.0` | 960 | @@ -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 | +7.5KB | +6.5KB | +7.5KB | +12.0KB | -| netstandard2.1 | 8.5KB | 312.5KB | +304.0KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | -| net461 | 8.5KB | 357.0KB | +348.5KB | +7.5KB | +6.5KB | +8.0KB | +12.5KB | -| net462 | 7.0KB | 360.5KB | +353.5KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | -| net47 | 7.0KB | 360.5KB | +353.5KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | -| net471 | 8.5KB | 359.5KB | +351.0KB | +7.5KB | +6.5KB | +7.5KB | +12.0KB | -| net472 | 8.5KB | 358.0KB | +349.5KB | +8.0KB | +6.5KB | +8.0KB | +12.5KB | -| net48 | 8.5KB | 358.0KB | +349.5KB | +8.0KB | +6.5KB | +8.0KB | +12.5KB | -| net481 | 8.5KB | 358.0KB | +349.5KB | +8.0KB | +6.5KB | +8.0KB | +12.5KB | -| netcoreapp2.0 | 9.0KB | 336.0KB | +327.0KB | +8.5KB | +6.5KB | +9.0KB | +13.5KB | -| netcoreapp2.1 | 9.0KB | 316.0KB | +307.0KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | -| netcoreapp2.2 | 9.0KB | 316.0KB | +307.0KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | -| netcoreapp3.0 | 9.5KB | 308.5KB | +299.0KB | +9.0KB | +6.5KB | +9.0KB | +14.0KB | -| netcoreapp3.1 | 9.5KB | 307.0KB | +297.5KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | -| net5.0 | 9.5KB | 271.0KB | +261.5KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | -| net6.0 | 10.0KB | 212.5KB | +202.5KB | +10.0KB | +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 | -| net10.0 | 10.0KB | 76.0KB | +66.0KB | +8.5KB | | +512bytes | +3.5KB | -| net11.0 | 10.0KB | 20.5KB | +10.5KB | +9.0KB | | +512bytes | +3.5KB | +| netstandard2.0 | 8.0KB | 359.0KB | +351.0KB | +7.5KB | +6.5KB | +8.0KB | +12.5KB | +| netstandard2.1 | 8.5KB | 313.0KB | +304.5KB | +9.0KB | +6.5KB | +9.0KB | +14.0KB | +| net461 | 8.5KB | 358.0KB | +349.5KB | +7.5KB | +6.5KB | +7.5KB | +12.0KB | +| net462 | 7.0KB | 361.5KB | +354.5KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | +| net47 | 7.0KB | 361.0KB | +354.0KB | +9.0KB | +6.5KB | +9.5KB | +14.0KB | +| net471 | 8.5KB | 360.5KB | +352.0KB | +7.5KB | +6.5KB | +7.5KB | +12.0KB | +| net472 | 8.5KB | 359.0KB | +350.5KB | +7.5KB | +6.5KB | +7.5KB | +12.0KB | +| net48 | 8.5KB | 359.0KB | +350.5KB | +7.5KB | +6.5KB | +7.5KB | +12.0KB | +| 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 | +14.0KB | +| netcoreapp2.2 | 9.0KB | 316.5KB | +307.5KB | +9.0KB | +6.5KB | +9.0KB | +14.0KB | +| netcoreapp3.0 | 9.5KB | 310.0KB | +300.5KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | +| netcoreapp3.1 | 9.5KB | 308.0KB | +298.5KB | +9.0KB | +6.5KB | +9.0KB | +14.0KB | +| net5.0 | 9.5KB | 272.0KB | +262.5KB | +9.0KB | +6.5KB | +9.0KB | +14.0KB | +| net6.0 | 10.0KB | 213.5KB | +203.5KB | +9.5KB | +6.5KB | +512bytes | +3.0KB | +| net7.0 | 10.0KB | 175.5KB | +165.5KB | +11.5KB | +8.0KB | +512bytes | +3.0KB | +| net8.0 | 9.5KB | 145.5KB | +136.0KB | +8.5KB | +512bytes | +1.0KB | +3.5KB | +| net9.0 | 9.5KB | 99.0KB | +89.5KB | +8.0KB | | +512bytes | +3.0KB | +| net10.0 | 10.0KB | 76.5KB | +66.5KB | +8.5KB | | +512bytes | +3.5KB | +| net11.0 | 10.0KB | 20.5KB | +10.5KB | +9.0KB | | +1.0KB | +4.0KB | ### Assembly Sizes with EmbedUntrackedSources | | Empty Assembly | With Polyfill | Diff | Ensure | ArgumentExceptions | StringInterpolation | Nullability | |----------------|----------------|---------------|-----------|-----------|--------------------|---------------------|-------------| -| netstandard2.0 | 8.0KB | 524.4KB | +516.4KB | +15.2KB | +8.2KB | +12.4KB | +17.4KB | -| netstandard2.1 | 8.5KB | 451.8KB | +443.3KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | -| net461 | 8.5KB | 524.0KB | +515.5KB | +15.2KB | +8.2KB | +12.9KB | +17.9KB | -| net462 | 7.0KB | 527.5KB | +520.5KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | -| net47 | 7.0KB | 527.2KB | +520.2KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | -| net471 | 8.5KB | 525.8KB | +517.3KB | +15.2KB | +8.2KB | +12.4KB | +17.4KB | -| net472 | 8.5KB | 523.3KB | +514.8KB | +15.7KB | +8.2KB | +12.9KB | +17.9KB | -| net48 | 8.5KB | 523.3KB | +514.8KB | +15.7KB | +8.2KB | +12.9KB | +17.9KB | -| net481 | 8.5KB | 523.3KB | +514.8KB | +15.7KB | +8.2KB | +12.9KB | +17.9KB | -| netcoreapp2.0 | 9.0KB | 491.3KB | +482.3KB | +16.2KB | +8.2KB | +13.9KB | +18.9KB | -| netcoreapp2.1 | 9.0KB | 459.0KB | +450.0KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | -| netcoreapp2.2 | 9.0KB | 459.0KB | +450.0KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | -| netcoreapp3.0 | 9.5KB | 442.7KB | +433.2KB | +16.7KB | +8.2KB | +13.9KB | +19.4KB | -| netcoreapp3.1 | 9.5KB | 441.2KB | +431.7KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | -| net5.0 | 9.5KB | 387.0KB | +377.5KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | -| net6.0 | 10.0KB | 308.4KB | +298.4KB | +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.3KB | +20.3KB | +16.5KB | | +1.1KB | +4.2KB | +| netstandard2.0 | 8.0KB | 525.8KB | +517.8KB | +15.2KB | +8.2KB | +12.9KB | +17.9KB | +| netstandard2.1 | 8.5KB | 453.2KB | +444.7KB | +16.7KB | +8.2KB | +13.9KB | +19.4KB | +| net461 | 8.5KB | 525.9KB | +517.4KB | +15.2KB | +8.2KB | +12.4KB | +17.4KB | +| net462 | 7.0KB | 529.4KB | +522.4KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | +| net47 | 7.0KB | 528.6KB | +521.6KB | +16.7KB | +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.2KB | +516.7KB | +15.2KB | +8.2KB | +12.4KB | +17.4KB | +| net48 | 8.5KB | 525.2KB | +516.7KB | +15.2KB | +8.2KB | +12.4KB | +17.4KB | +| net481 | 8.5KB | 525.2KB | +516.7KB | +15.2KB | +8.2KB | +12.4KB | +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 | +13.9KB | +19.4KB | +| netcoreapp3.0 | 9.5KB | 445.0KB | +435.5KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | +| netcoreapp3.1 | 9.5KB | 443.0KB | +433.5KB | +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.2KB | +1.1KB | +3.7KB | +| net7.0 | 10.0KB | 253.2KB | +243.2KB | +19.1KB | +9.4KB | +1.1KB | +3.7KB | +| net8.0 | 9.5KB | 207.7KB | +198.2KB | +16.0KB | +811bytes | +1.6KB | +4.2KB | +| net9.0 | 9.5KB | 140.1KB | +130.6KB | +15.5KB | | +1.1KB | +3.7KB | +| net10.0 | 10.0KB | 108.9KB | +98.9KB | +16.0KB | | +1.1KB | +4.2KB | +| net11.0 | 10.0KB | 30.4KB | +20.4KB | +16.5KB | | +1.6KB | +4.7KB | @@ -2267,7 +2267,7 @@ void ObjectDisposedExceptionExample(bool isDisposed) ObjectDisposedException.ThrowIf(isDisposed, typeof(Consume)); } ``` -snippet source | anchor +snippet source | anchor @@ -2286,7 +2286,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/Consume/Consume.cs b/src/Consume/Consume.cs index 267d3e89..868deba1 100644 --- a/src/Consume/Consume.cs +++ b/src/Consume/Consume.cs @@ -109,6 +109,7 @@ class Consume #endif type = typeof(AsyncMethodBuilderAttribute); type = typeof(CompilerLoweringPreserveAttribute); + type = typeof(IsClosedTypeAttribute); #if !NET6_0 && !NET5_0 type = typeof(ObsoletedOSPlatformAttribute); type = typeof(SupportedOSPlatformGuardAttribute); diff --git a/src/Polyfill/IsClosedTypeAttribute.cs b/src/Polyfill/IsClosedTypeAttribute.cs new file mode 100644 index 00000000..500de7be --- /dev/null +++ b/src/Polyfill/IsClosedTypeAttribute.cs @@ -0,0 +1,40 @@ +#if !NET11_0_OR_GREATER + +namespace System.Runtime.CompilerServices; + +using Diagnostics; +using Diagnostics.CodeAnalysis; + +/// +/// Reserved for use by a compiler for tracking metadata. +/// This attribute should not be used by developers in source code. +/// +[ExcludeFromCodeCoverage] +[DebuggerNonUserCode] +[AttributeUsage(AttributeTargets.Class, Inherited = false)] +#if PolyUseEmbeddedAttribute +[global::Microsoft.CodeAnalysis.EmbeddedAttribute] +#endif +//Link: https://learn.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.isclosedtypeattribute?view=net-11.0 +#if PolyPublic +public +#endif +sealed class IsClosedTypeAttribute : + Attribute +{ + Type[] derivedTypes = Type.EmptyTypes; + + /// + /// Gets or sets the derived types of the closed type. + /// A value is normalized to an empty array. + /// + public Type[] DerivedTypes + { + get => derivedTypes; + set => derivedTypes = value ?? Type.EmptyTypes; + } +} + +#else +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Runtime.CompilerServices.IsClosedTypeAttribute))] +#endif diff --git a/src/Split/net10.0/IsClosedTypeAttribute.cs b/src/Split/net10.0/IsClosedTypeAttribute.cs new file mode 100644 index 00000000..ad49e22f --- /dev/null +++ b/src/Split/net10.0/IsClosedTypeAttribute.cs @@ -0,0 +1,32 @@ +// +#pragma warning disable +namespace System.Runtime.CompilerServices; +using Diagnostics; +using Diagnostics.CodeAnalysis; +/// +/// Reserved for use by a compiler for tracking metadata. +/// This attribute should not be used by developers in source code. +/// +[ExcludeFromCodeCoverage] +[DebuggerNonUserCode] +[AttributeUsage(AttributeTargets.Class, Inherited = false)] +#if PolyUseEmbeddedAttribute +[global::Microsoft.CodeAnalysis.EmbeddedAttribute] +#endif +#if PolyPublic +public +#endif +sealed class IsClosedTypeAttribute : + Attribute +{ + Type[] derivedTypes = Type.EmptyTypes; + /// + /// Gets or sets the derived types of the closed type. + /// A value is normalized to an empty array. + /// + public Type[] DerivedTypes + { + get => derivedTypes; + set => derivedTypes = value ?? Type.EmptyTypes; + } +} diff --git a/src/Split/net11.0/TypeForwardeds.cs b/src/Split/net11.0/TypeForwardeds.cs index f93df98b..435914d1 100644 --- a/src/Split/net11.0/TypeForwardeds.cs +++ b/src/Split/net11.0/TypeForwardeds.cs @@ -18,6 +18,7 @@ [assembly: TypeForwardedTo(typeof(System.Diagnostics.CodeAnalysis.FeatureGuardAttribute))] [assembly: TypeForwardedTo(typeof(System.Diagnostics.CodeAnalysis.FeatureSwitchDefinitionAttribute))] [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.Collections.Generic.KeyValuePair))] [assembly: TypeForwardedTo(typeof(System.Threading.Lock))] diff --git a/src/Split/net461/IsClosedTypeAttribute.cs b/src/Split/net461/IsClosedTypeAttribute.cs new file mode 100644 index 00000000..ad49e22f --- /dev/null +++ b/src/Split/net461/IsClosedTypeAttribute.cs @@ -0,0 +1,32 @@ +// +#pragma warning disable +namespace System.Runtime.CompilerServices; +using Diagnostics; +using Diagnostics.CodeAnalysis; +/// +/// Reserved for use by a compiler for tracking metadata. +/// This attribute should not be used by developers in source code. +/// +[ExcludeFromCodeCoverage] +[DebuggerNonUserCode] +[AttributeUsage(AttributeTargets.Class, Inherited = false)] +#if PolyUseEmbeddedAttribute +[global::Microsoft.CodeAnalysis.EmbeddedAttribute] +#endif +#if PolyPublic +public +#endif +sealed class IsClosedTypeAttribute : + Attribute +{ + Type[] derivedTypes = Type.EmptyTypes; + /// + /// Gets or sets the derived types of the closed type. + /// A value is normalized to an empty array. + /// + public Type[] DerivedTypes + { + get => derivedTypes; + set => derivedTypes = value ?? Type.EmptyTypes; + } +} diff --git a/src/Split/net462/IsClosedTypeAttribute.cs b/src/Split/net462/IsClosedTypeAttribute.cs new file mode 100644 index 00000000..ad49e22f --- /dev/null +++ b/src/Split/net462/IsClosedTypeAttribute.cs @@ -0,0 +1,32 @@ +// +#pragma warning disable +namespace System.Runtime.CompilerServices; +using Diagnostics; +using Diagnostics.CodeAnalysis; +/// +/// Reserved for use by a compiler for tracking metadata. +/// This attribute should not be used by developers in source code. +/// +[ExcludeFromCodeCoverage] +[DebuggerNonUserCode] +[AttributeUsage(AttributeTargets.Class, Inherited = false)] +#if PolyUseEmbeddedAttribute +[global::Microsoft.CodeAnalysis.EmbeddedAttribute] +#endif +#if PolyPublic +public +#endif +sealed class IsClosedTypeAttribute : + Attribute +{ + Type[] derivedTypes = Type.EmptyTypes; + /// + /// Gets or sets the derived types of the closed type. + /// A value is normalized to an empty array. + /// + public Type[] DerivedTypes + { + get => derivedTypes; + set => derivedTypes = value ?? Type.EmptyTypes; + } +} diff --git a/src/Split/net47/IsClosedTypeAttribute.cs b/src/Split/net47/IsClosedTypeAttribute.cs new file mode 100644 index 00000000..ad49e22f --- /dev/null +++ b/src/Split/net47/IsClosedTypeAttribute.cs @@ -0,0 +1,32 @@ +// +#pragma warning disable +namespace System.Runtime.CompilerServices; +using Diagnostics; +using Diagnostics.CodeAnalysis; +/// +/// Reserved for use by a compiler for tracking metadata. +/// This attribute should not be used by developers in source code. +/// +[ExcludeFromCodeCoverage] +[DebuggerNonUserCode] +[AttributeUsage(AttributeTargets.Class, Inherited = false)] +#if PolyUseEmbeddedAttribute +[global::Microsoft.CodeAnalysis.EmbeddedAttribute] +#endif +#if PolyPublic +public +#endif +sealed class IsClosedTypeAttribute : + Attribute +{ + Type[] derivedTypes = Type.EmptyTypes; + /// + /// Gets or sets the derived types of the closed type. + /// A value is normalized to an empty array. + /// + public Type[] DerivedTypes + { + get => derivedTypes; + set => derivedTypes = value ?? Type.EmptyTypes; + } +} diff --git a/src/Split/net471/IsClosedTypeAttribute.cs b/src/Split/net471/IsClosedTypeAttribute.cs new file mode 100644 index 00000000..ad49e22f --- /dev/null +++ b/src/Split/net471/IsClosedTypeAttribute.cs @@ -0,0 +1,32 @@ +// +#pragma warning disable +namespace System.Runtime.CompilerServices; +using Diagnostics; +using Diagnostics.CodeAnalysis; +/// +/// Reserved for use by a compiler for tracking metadata. +/// This attribute should not be used by developers in source code. +/// +[ExcludeFromCodeCoverage] +[DebuggerNonUserCode] +[AttributeUsage(AttributeTargets.Class, Inherited = false)] +#if PolyUseEmbeddedAttribute +[global::Microsoft.CodeAnalysis.EmbeddedAttribute] +#endif +#if PolyPublic +public +#endif +sealed class IsClosedTypeAttribute : + Attribute +{ + Type[] derivedTypes = Type.EmptyTypes; + /// + /// Gets or sets the derived types of the closed type. + /// A value is normalized to an empty array. + /// + public Type[] DerivedTypes + { + get => derivedTypes; + set => derivedTypes = value ?? Type.EmptyTypes; + } +} diff --git a/src/Split/net472/IsClosedTypeAttribute.cs b/src/Split/net472/IsClosedTypeAttribute.cs new file mode 100644 index 00000000..ad49e22f --- /dev/null +++ b/src/Split/net472/IsClosedTypeAttribute.cs @@ -0,0 +1,32 @@ +// +#pragma warning disable +namespace System.Runtime.CompilerServices; +using Diagnostics; +using Diagnostics.CodeAnalysis; +/// +/// Reserved for use by a compiler for tracking metadata. +/// This attribute should not be used by developers in source code. +/// +[ExcludeFromCodeCoverage] +[DebuggerNonUserCode] +[AttributeUsage(AttributeTargets.Class, Inherited = false)] +#if PolyUseEmbeddedAttribute +[global::Microsoft.CodeAnalysis.EmbeddedAttribute] +#endif +#if PolyPublic +public +#endif +sealed class IsClosedTypeAttribute : + Attribute +{ + Type[] derivedTypes = Type.EmptyTypes; + /// + /// Gets or sets the derived types of the closed type. + /// A value is normalized to an empty array. + /// + public Type[] DerivedTypes + { + get => derivedTypes; + set => derivedTypes = value ?? Type.EmptyTypes; + } +} diff --git a/src/Split/net48/IsClosedTypeAttribute.cs b/src/Split/net48/IsClosedTypeAttribute.cs new file mode 100644 index 00000000..ad49e22f --- /dev/null +++ b/src/Split/net48/IsClosedTypeAttribute.cs @@ -0,0 +1,32 @@ +// +#pragma warning disable +namespace System.Runtime.CompilerServices; +using Diagnostics; +using Diagnostics.CodeAnalysis; +/// +/// Reserved for use by a compiler for tracking metadata. +/// This attribute should not be used by developers in source code. +/// +[ExcludeFromCodeCoverage] +[DebuggerNonUserCode] +[AttributeUsage(AttributeTargets.Class, Inherited = false)] +#if PolyUseEmbeddedAttribute +[global::Microsoft.CodeAnalysis.EmbeddedAttribute] +#endif +#if PolyPublic +public +#endif +sealed class IsClosedTypeAttribute : + Attribute +{ + Type[] derivedTypes = Type.EmptyTypes; + /// + /// Gets or sets the derived types of the closed type. + /// A value is normalized to an empty array. + /// + public Type[] DerivedTypes + { + get => derivedTypes; + set => derivedTypes = value ?? Type.EmptyTypes; + } +} diff --git a/src/Split/net481/IsClosedTypeAttribute.cs b/src/Split/net481/IsClosedTypeAttribute.cs new file mode 100644 index 00000000..ad49e22f --- /dev/null +++ b/src/Split/net481/IsClosedTypeAttribute.cs @@ -0,0 +1,32 @@ +// +#pragma warning disable +namespace System.Runtime.CompilerServices; +using Diagnostics; +using Diagnostics.CodeAnalysis; +/// +/// Reserved for use by a compiler for tracking metadata. +/// This attribute should not be used by developers in source code. +/// +[ExcludeFromCodeCoverage] +[DebuggerNonUserCode] +[AttributeUsage(AttributeTargets.Class, Inherited = false)] +#if PolyUseEmbeddedAttribute +[global::Microsoft.CodeAnalysis.EmbeddedAttribute] +#endif +#if PolyPublic +public +#endif +sealed class IsClosedTypeAttribute : + Attribute +{ + Type[] derivedTypes = Type.EmptyTypes; + /// + /// Gets or sets the derived types of the closed type. + /// A value is normalized to an empty array. + /// + public Type[] DerivedTypes + { + get => derivedTypes; + set => derivedTypes = value ?? Type.EmptyTypes; + } +} diff --git a/src/Split/net5.0/IsClosedTypeAttribute.cs b/src/Split/net5.0/IsClosedTypeAttribute.cs new file mode 100644 index 00000000..ad49e22f --- /dev/null +++ b/src/Split/net5.0/IsClosedTypeAttribute.cs @@ -0,0 +1,32 @@ +// +#pragma warning disable +namespace System.Runtime.CompilerServices; +using Diagnostics; +using Diagnostics.CodeAnalysis; +/// +/// Reserved for use by a compiler for tracking metadata. +/// This attribute should not be used by developers in source code. +/// +[ExcludeFromCodeCoverage] +[DebuggerNonUserCode] +[AttributeUsage(AttributeTargets.Class, Inherited = false)] +#if PolyUseEmbeddedAttribute +[global::Microsoft.CodeAnalysis.EmbeddedAttribute] +#endif +#if PolyPublic +public +#endif +sealed class IsClosedTypeAttribute : + Attribute +{ + Type[] derivedTypes = Type.EmptyTypes; + /// + /// Gets or sets the derived types of the closed type. + /// A value is normalized to an empty array. + /// + public Type[] DerivedTypes + { + get => derivedTypes; + set => derivedTypes = value ?? Type.EmptyTypes; + } +} diff --git a/src/Split/net6.0/IsClosedTypeAttribute.cs b/src/Split/net6.0/IsClosedTypeAttribute.cs new file mode 100644 index 00000000..ad49e22f --- /dev/null +++ b/src/Split/net6.0/IsClosedTypeAttribute.cs @@ -0,0 +1,32 @@ +// +#pragma warning disable +namespace System.Runtime.CompilerServices; +using Diagnostics; +using Diagnostics.CodeAnalysis; +/// +/// Reserved for use by a compiler for tracking metadata. +/// This attribute should not be used by developers in source code. +/// +[ExcludeFromCodeCoverage] +[DebuggerNonUserCode] +[AttributeUsage(AttributeTargets.Class, Inherited = false)] +#if PolyUseEmbeddedAttribute +[global::Microsoft.CodeAnalysis.EmbeddedAttribute] +#endif +#if PolyPublic +public +#endif +sealed class IsClosedTypeAttribute : + Attribute +{ + Type[] derivedTypes = Type.EmptyTypes; + /// + /// Gets or sets the derived types of the closed type. + /// A value is normalized to an empty array. + /// + public Type[] DerivedTypes + { + get => derivedTypes; + set => derivedTypes = value ?? Type.EmptyTypes; + } +} diff --git a/src/Split/net7.0/IsClosedTypeAttribute.cs b/src/Split/net7.0/IsClosedTypeAttribute.cs new file mode 100644 index 00000000..ad49e22f --- /dev/null +++ b/src/Split/net7.0/IsClosedTypeAttribute.cs @@ -0,0 +1,32 @@ +// +#pragma warning disable +namespace System.Runtime.CompilerServices; +using Diagnostics; +using Diagnostics.CodeAnalysis; +/// +/// Reserved for use by a compiler for tracking metadata. +/// This attribute should not be used by developers in source code. +/// +[ExcludeFromCodeCoverage] +[DebuggerNonUserCode] +[AttributeUsage(AttributeTargets.Class, Inherited = false)] +#if PolyUseEmbeddedAttribute +[global::Microsoft.CodeAnalysis.EmbeddedAttribute] +#endif +#if PolyPublic +public +#endif +sealed class IsClosedTypeAttribute : + Attribute +{ + Type[] derivedTypes = Type.EmptyTypes; + /// + /// Gets or sets the derived types of the closed type. + /// A value is normalized to an empty array. + /// + public Type[] DerivedTypes + { + get => derivedTypes; + set => derivedTypes = value ?? Type.EmptyTypes; + } +} diff --git a/src/Split/net8.0/IsClosedTypeAttribute.cs b/src/Split/net8.0/IsClosedTypeAttribute.cs new file mode 100644 index 00000000..ad49e22f --- /dev/null +++ b/src/Split/net8.0/IsClosedTypeAttribute.cs @@ -0,0 +1,32 @@ +// +#pragma warning disable +namespace System.Runtime.CompilerServices; +using Diagnostics; +using Diagnostics.CodeAnalysis; +/// +/// Reserved for use by a compiler for tracking metadata. +/// This attribute should not be used by developers in source code. +/// +[ExcludeFromCodeCoverage] +[DebuggerNonUserCode] +[AttributeUsage(AttributeTargets.Class, Inherited = false)] +#if PolyUseEmbeddedAttribute +[global::Microsoft.CodeAnalysis.EmbeddedAttribute] +#endif +#if PolyPublic +public +#endif +sealed class IsClosedTypeAttribute : + Attribute +{ + Type[] derivedTypes = Type.EmptyTypes; + /// + /// Gets or sets the derived types of the closed type. + /// A value is normalized to an empty array. + /// + public Type[] DerivedTypes + { + get => derivedTypes; + set => derivedTypes = value ?? Type.EmptyTypes; + } +} diff --git a/src/Split/net9.0/IsClosedTypeAttribute.cs b/src/Split/net9.0/IsClosedTypeAttribute.cs new file mode 100644 index 00000000..ad49e22f --- /dev/null +++ b/src/Split/net9.0/IsClosedTypeAttribute.cs @@ -0,0 +1,32 @@ +// +#pragma warning disable +namespace System.Runtime.CompilerServices; +using Diagnostics; +using Diagnostics.CodeAnalysis; +/// +/// Reserved for use by a compiler for tracking metadata. +/// This attribute should not be used by developers in source code. +/// +[ExcludeFromCodeCoverage] +[DebuggerNonUserCode] +[AttributeUsage(AttributeTargets.Class, Inherited = false)] +#if PolyUseEmbeddedAttribute +[global::Microsoft.CodeAnalysis.EmbeddedAttribute] +#endif +#if PolyPublic +public +#endif +sealed class IsClosedTypeAttribute : + Attribute +{ + Type[] derivedTypes = Type.EmptyTypes; + /// + /// Gets or sets the derived types of the closed type. + /// A value is normalized to an empty array. + /// + public Type[] DerivedTypes + { + get => derivedTypes; + set => derivedTypes = value ?? Type.EmptyTypes; + } +} diff --git a/src/Split/netcoreapp2.0/IsClosedTypeAttribute.cs b/src/Split/netcoreapp2.0/IsClosedTypeAttribute.cs new file mode 100644 index 00000000..ad49e22f --- /dev/null +++ b/src/Split/netcoreapp2.0/IsClosedTypeAttribute.cs @@ -0,0 +1,32 @@ +// +#pragma warning disable +namespace System.Runtime.CompilerServices; +using Diagnostics; +using Diagnostics.CodeAnalysis; +/// +/// Reserved for use by a compiler for tracking metadata. +/// This attribute should not be used by developers in source code. +/// +[ExcludeFromCodeCoverage] +[DebuggerNonUserCode] +[AttributeUsage(AttributeTargets.Class, Inherited = false)] +#if PolyUseEmbeddedAttribute +[global::Microsoft.CodeAnalysis.EmbeddedAttribute] +#endif +#if PolyPublic +public +#endif +sealed class IsClosedTypeAttribute : + Attribute +{ + Type[] derivedTypes = Type.EmptyTypes; + /// + /// Gets or sets the derived types of the closed type. + /// A value is normalized to an empty array. + /// + public Type[] DerivedTypes + { + get => derivedTypes; + set => derivedTypes = value ?? Type.EmptyTypes; + } +} diff --git a/src/Split/netcoreapp2.1/IsClosedTypeAttribute.cs b/src/Split/netcoreapp2.1/IsClosedTypeAttribute.cs new file mode 100644 index 00000000..ad49e22f --- /dev/null +++ b/src/Split/netcoreapp2.1/IsClosedTypeAttribute.cs @@ -0,0 +1,32 @@ +// +#pragma warning disable +namespace System.Runtime.CompilerServices; +using Diagnostics; +using Diagnostics.CodeAnalysis; +/// +/// Reserved for use by a compiler for tracking metadata. +/// This attribute should not be used by developers in source code. +/// +[ExcludeFromCodeCoverage] +[DebuggerNonUserCode] +[AttributeUsage(AttributeTargets.Class, Inherited = false)] +#if PolyUseEmbeddedAttribute +[global::Microsoft.CodeAnalysis.EmbeddedAttribute] +#endif +#if PolyPublic +public +#endif +sealed class IsClosedTypeAttribute : + Attribute +{ + Type[] derivedTypes = Type.EmptyTypes; + /// + /// Gets or sets the derived types of the closed type. + /// A value is normalized to an empty array. + /// + public Type[] DerivedTypes + { + get => derivedTypes; + set => derivedTypes = value ?? Type.EmptyTypes; + } +} diff --git a/src/Split/netcoreapp2.2/IsClosedTypeAttribute.cs b/src/Split/netcoreapp2.2/IsClosedTypeAttribute.cs new file mode 100644 index 00000000..ad49e22f --- /dev/null +++ b/src/Split/netcoreapp2.2/IsClosedTypeAttribute.cs @@ -0,0 +1,32 @@ +// +#pragma warning disable +namespace System.Runtime.CompilerServices; +using Diagnostics; +using Diagnostics.CodeAnalysis; +/// +/// Reserved for use by a compiler for tracking metadata. +/// This attribute should not be used by developers in source code. +/// +[ExcludeFromCodeCoverage] +[DebuggerNonUserCode] +[AttributeUsage(AttributeTargets.Class, Inherited = false)] +#if PolyUseEmbeddedAttribute +[global::Microsoft.CodeAnalysis.EmbeddedAttribute] +#endif +#if PolyPublic +public +#endif +sealed class IsClosedTypeAttribute : + Attribute +{ + Type[] derivedTypes = Type.EmptyTypes; + /// + /// Gets or sets the derived types of the closed type. + /// A value is normalized to an empty array. + /// + public Type[] DerivedTypes + { + get => derivedTypes; + set => derivedTypes = value ?? Type.EmptyTypes; + } +} diff --git a/src/Split/netcoreapp3.0/IsClosedTypeAttribute.cs b/src/Split/netcoreapp3.0/IsClosedTypeAttribute.cs new file mode 100644 index 00000000..ad49e22f --- /dev/null +++ b/src/Split/netcoreapp3.0/IsClosedTypeAttribute.cs @@ -0,0 +1,32 @@ +// +#pragma warning disable +namespace System.Runtime.CompilerServices; +using Diagnostics; +using Diagnostics.CodeAnalysis; +/// +/// Reserved for use by a compiler for tracking metadata. +/// This attribute should not be used by developers in source code. +/// +[ExcludeFromCodeCoverage] +[DebuggerNonUserCode] +[AttributeUsage(AttributeTargets.Class, Inherited = false)] +#if PolyUseEmbeddedAttribute +[global::Microsoft.CodeAnalysis.EmbeddedAttribute] +#endif +#if PolyPublic +public +#endif +sealed class IsClosedTypeAttribute : + Attribute +{ + Type[] derivedTypes = Type.EmptyTypes; + /// + /// Gets or sets the derived types of the closed type. + /// A value is normalized to an empty array. + /// + public Type[] DerivedTypes + { + get => derivedTypes; + set => derivedTypes = value ?? Type.EmptyTypes; + } +} diff --git a/src/Split/netcoreapp3.1/IsClosedTypeAttribute.cs b/src/Split/netcoreapp3.1/IsClosedTypeAttribute.cs new file mode 100644 index 00000000..ad49e22f --- /dev/null +++ b/src/Split/netcoreapp3.1/IsClosedTypeAttribute.cs @@ -0,0 +1,32 @@ +// +#pragma warning disable +namespace System.Runtime.CompilerServices; +using Diagnostics; +using Diagnostics.CodeAnalysis; +/// +/// Reserved for use by a compiler for tracking metadata. +/// This attribute should not be used by developers in source code. +/// +[ExcludeFromCodeCoverage] +[DebuggerNonUserCode] +[AttributeUsage(AttributeTargets.Class, Inherited = false)] +#if PolyUseEmbeddedAttribute +[global::Microsoft.CodeAnalysis.EmbeddedAttribute] +#endif +#if PolyPublic +public +#endif +sealed class IsClosedTypeAttribute : + Attribute +{ + Type[] derivedTypes = Type.EmptyTypes; + /// + /// Gets or sets the derived types of the closed type. + /// A value is normalized to an empty array. + /// + public Type[] DerivedTypes + { + get => derivedTypes; + set => derivedTypes = value ?? Type.EmptyTypes; + } +} diff --git a/src/Split/netstandard2.0/IsClosedTypeAttribute.cs b/src/Split/netstandard2.0/IsClosedTypeAttribute.cs new file mode 100644 index 00000000..ad49e22f --- /dev/null +++ b/src/Split/netstandard2.0/IsClosedTypeAttribute.cs @@ -0,0 +1,32 @@ +// +#pragma warning disable +namespace System.Runtime.CompilerServices; +using Diagnostics; +using Diagnostics.CodeAnalysis; +/// +/// Reserved for use by a compiler for tracking metadata. +/// This attribute should not be used by developers in source code. +/// +[ExcludeFromCodeCoverage] +[DebuggerNonUserCode] +[AttributeUsage(AttributeTargets.Class, Inherited = false)] +#if PolyUseEmbeddedAttribute +[global::Microsoft.CodeAnalysis.EmbeddedAttribute] +#endif +#if PolyPublic +public +#endif +sealed class IsClosedTypeAttribute : + Attribute +{ + Type[] derivedTypes = Type.EmptyTypes; + /// + /// Gets or sets the derived types of the closed type. + /// A value is normalized to an empty array. + /// + public Type[] DerivedTypes + { + get => derivedTypes; + set => derivedTypes = value ?? Type.EmptyTypes; + } +} diff --git a/src/Split/netstandard2.1/IsClosedTypeAttribute.cs b/src/Split/netstandard2.1/IsClosedTypeAttribute.cs new file mode 100644 index 00000000..ad49e22f --- /dev/null +++ b/src/Split/netstandard2.1/IsClosedTypeAttribute.cs @@ -0,0 +1,32 @@ +// +#pragma warning disable +namespace System.Runtime.CompilerServices; +using Diagnostics; +using Diagnostics.CodeAnalysis; +/// +/// Reserved for use by a compiler for tracking metadata. +/// This attribute should not be used by developers in source code. +/// +[ExcludeFromCodeCoverage] +[DebuggerNonUserCode] +[AttributeUsage(AttributeTargets.Class, Inherited = false)] +#if PolyUseEmbeddedAttribute +[global::Microsoft.CodeAnalysis.EmbeddedAttribute] +#endif +#if PolyPublic +public +#endif +sealed class IsClosedTypeAttribute : + Attribute +{ + Type[] derivedTypes = Type.EmptyTypes; + /// + /// Gets or sets the derived types of the closed type. + /// A value is normalized to an empty array. + /// + public Type[] DerivedTypes + { + get => derivedTypes; + set => derivedTypes = value ?? Type.EmptyTypes; + } +} diff --git a/src/Split/uap10.0/IsClosedTypeAttribute.cs b/src/Split/uap10.0/IsClosedTypeAttribute.cs new file mode 100644 index 00000000..ad49e22f --- /dev/null +++ b/src/Split/uap10.0/IsClosedTypeAttribute.cs @@ -0,0 +1,32 @@ +// +#pragma warning disable +namespace System.Runtime.CompilerServices; +using Diagnostics; +using Diagnostics.CodeAnalysis; +/// +/// Reserved for use by a compiler for tracking metadata. +/// This attribute should not be used by developers in source code. +/// +[ExcludeFromCodeCoverage] +[DebuggerNonUserCode] +[AttributeUsage(AttributeTargets.Class, Inherited = false)] +#if PolyUseEmbeddedAttribute +[global::Microsoft.CodeAnalysis.EmbeddedAttribute] +#endif +#if PolyPublic +public +#endif +sealed class IsClosedTypeAttribute : + Attribute +{ + Type[] derivedTypes = Type.EmptyTypes; + /// + /// Gets or sets the derived types of the closed type. + /// A value is normalized to an empty array. + /// + public Type[] DerivedTypes + { + get => derivedTypes; + set => derivedTypes = value ?? Type.EmptyTypes; + } +} From 5d0389141dc2e9f0fc863ffd9c89b4574323b22a Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Mon, 7 Sep 2026 13:54:47 +1000 Subject: [PATCH 2/4] Update global.json --- global.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/global.json b/global.json index 3fe8c1bb..a764113f 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "11.0.100-preview.7.26381.103", + "version": "11.0.100-rc.1.26431.118", "allowPrerelease": true, "rollForward": "latestFeature" }, From 7107dc52cbe920298af0eca9a561861bf28ce607 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Mon, 7 Sep 2026 15:54:48 +1000 Subject: [PATCH 3/4] . --- src/ConsumeCsPreview/ClosedHierarchy.cs | 37 ++++++++++++++++++++ src/ConsumeCsPreview/ConsumeCsPreview.csproj | 20 +++++++++++ src/Polyfill.slnx | 1 + 3 files changed, 58 insertions(+) create mode 100644 src/ConsumeCsPreview/ClosedHierarchy.cs create mode 100644 src/ConsumeCsPreview/ConsumeCsPreview.csproj diff --git a/src/ConsumeCsPreview/ClosedHierarchy.cs b/src/ConsumeCsPreview/ClosedHierarchy.cs new file mode 100644 index 00000000..f485afd8 --- /dev/null +++ b/src/ConsumeCsPreview/ClosedHierarchy.cs @@ -0,0 +1,37 @@ +namespace ConsumeCsPreview; + +/// +/// Compile-only coverage for the C# `closed` modifier. The compiler emits +/// IsClosedTypeAttribute on the closed type and +/// CompilerFeatureRequiredAttribute("ClosedClasses") on its constructors, +/// so this only compiles when both are polyfilled. +/// +closed class JobStatus; + +sealed class Queued : JobStatus; + +sealed class Running(int percentComplete) : JobStatus +{ + public int PercentComplete => percentComplete; +} + +sealed class Failed(string error) : JobStatus +{ + public string Error => error; +} + +static class ClosedHierarchy +{ + /// + /// No default arm: the switch is exhaustive because every direct descendant of the + /// closed is handled. Without exhaustiveness this warns CS8509, + /// which is an error since TreatWarningsAsErrors is enabled. + /// + public static string Describe(JobStatus status) => + status switch + { + Queued => "queued", + Running running => $"{running.PercentComplete}% complete", + Failed failed => $"failed: {failed.Error}" + }; +} diff --git a/src/ConsumeCsPreview/ConsumeCsPreview.csproj b/src/ConsumeCsPreview/ConsumeCsPreview.csproj new file mode 100644 index 00000000..0b4b7ab8 --- /dev/null +++ b/src/ConsumeCsPreview/ConsumeCsPreview.csproj @@ -0,0 +1,20 @@ + + + $(NoWarn);PolyfillTargetsForNuget + true + preview + net461;net462;net47;net471;net472;net48;net481;net6.0-windows + $(TargetFrameworks);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 + + + + + + + + + + + + + diff --git a/src/Polyfill.slnx b/src/Polyfill.slnx index 621fc120..aa8c9d42 100644 --- a/src/Polyfill.slnx +++ b/src/Polyfill.slnx @@ -29,6 +29,7 @@ + From 2bac90bc4262d2b63184fb88beed48a26a5e56f6 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Wed, 9 Sep 2026 11:01:14 +1000 Subject: [PATCH 4/4] . --- assemblySize.include.md | 4 +- readme.md | 52 ++++++++++++++++++++++++- src/ConsumeCsPreview/ClosedHierarchy.cs | 23 +++++------ 3 files changed, 64 insertions(+), 15 deletions(-) diff --git a/assemblySize.include.md b/assemblySize.include.md index 232d8d2d..53a66375 100644 --- a/assemblySize.include.md +++ b/assemblySize.include.md @@ -22,7 +22,7 @@ | net8.0 | 9.5KB | 145.5KB | +136.0KB | +8.5KB | +512bytes | +1.0KB | +3.5KB | | net9.0 | 9.5KB | 99.0KB | +89.5KB | +8.0KB | | +512bytes | +3.0KB | | net10.0 | 10.0KB | 76.5KB | +66.5KB | +8.5KB | | +512bytes | +3.5KB | -| net11.0 | 10.0KB | 20.5KB | +10.5KB | +9.0KB | | +1.0KB | +4.0KB | +| net11.0 | 10.0KB | 20.5KB | +10.5KB | +9.0KB | | +1.0KB | +3.5KB | ### Assembly Sizes with EmbedUntrackedSources @@ -49,4 +49,4 @@ | net8.0 | 9.5KB | 207.7KB | +198.2KB | +16.0KB | +811bytes | +1.6KB | +4.2KB | | net9.0 | 9.5KB | 140.1KB | +130.6KB | +15.5KB | | +1.1KB | +3.7KB | | net10.0 | 10.0KB | 108.9KB | +98.9KB | +16.0KB | | +1.1KB | +4.2KB | -| net11.0 | 10.0KB | 30.4KB | +20.4KB | +16.5KB | | +1.6KB | +4.7KB | +| net11.0 | 10.0KB | 30.4KB | +20.4KB | +16.5KB | | +1.6KB | +4.2KB | diff --git a/readme.md b/readme.md index e536bfd7..8ee60d25 100644 --- a/readme.md +++ b/readme.md @@ -116,7 +116,7 @@ This project uses features from the newest stable SDK and C# language. As such c | net8.0 | 9.5KB | 145.5KB | +136.0KB | +8.5KB | +512bytes | +1.0KB | +3.5KB | | net9.0 | 9.5KB | 99.0KB | +89.5KB | +8.0KB | | +512bytes | +3.0KB | | net10.0 | 10.0KB | 76.5KB | +66.5KB | +8.5KB | | +512bytes | +3.5KB | -| net11.0 | 10.0KB | 20.5KB | +10.5KB | +9.0KB | | +1.0KB | +4.0KB | +| net11.0 | 10.0KB | 20.5KB | +10.5KB | +9.0KB | | +1.0KB | +3.5KB | ### Assembly Sizes with EmbedUntrackedSources @@ -143,7 +143,7 @@ This project uses features from the newest stable SDK and C# language. As such c | net8.0 | 9.5KB | 207.7KB | +198.2KB | +16.0KB | +811bytes | +1.6KB | +4.2KB | | net9.0 | 9.5KB | 140.1KB | +130.6KB | +15.5KB | | +1.1KB | +3.7KB | | net10.0 | 10.0KB | 108.9KB | +98.9KB | +16.0KB | | +1.1KB | +4.2KB | -| net11.0 | 10.0KB | 30.4KB | +20.4KB | +16.5KB | | +1.6KB | +4.7KB | +| net11.0 | 10.0KB | 30.4KB | +20.4KB | +16.5KB | | +1.6KB | +4.2KB | @@ -260,6 +260,54 @@ public class Person > Indicates that compiler support for a particular feature is required for the location where this attribute is applied. +### IsClosedTypeAttribute + + * [IsClosedTypeAttribute](https://learn.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.isclosedtypeattribute) + +Reference: [Closed hierarchies](https://github.com/dotnet/csharplang/blob/main/proposals/csharp-15.0/closed-hierarchies.md) + +> Emitted by the compiler on a type declared with the `closed` modifier. It records the derived types the compiler found in the declaring file, which allows consumers to treat a switch over those types as exhaustive. + +Note that the C# `closed` modifier also requires [CompilerFeatureRequiredAttribute](#compilerfeaturerequiredattribute), which is also polyfilled. + + +#### Usage + + + +```cs +// Only types in this file can derive from JobStatus +closed class JobStatus; + +sealed class Queued : JobStatus; + +sealed class Running(int percentComplete) : JobStatus +{ + public int PercentComplete => percentComplete; +} + +sealed class Failed(string error) : JobStatus +{ + public string Error => error; +} + +static class ClosedHierarchy +{ + // No default arm: the switch is exhaustive because every direct descendant of + // the closed JobStatus is handled. Without exhaustiveness this warns CS8509. + public static string Describe(JobStatus status) => + status switch + { + Queued => "queued", + Running running => $"{running.PercentComplete}% complete", + Failed failed => $"failed: {failed.Error}" + }; +} +``` +snippet source | anchor + + + ### CollectionBuilderAttribute * [CollectionBuilderAttribute](https://learn.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.collectionbuilderattribute) diff --git a/src/ConsumeCsPreview/ClosedHierarchy.cs b/src/ConsumeCsPreview/ClosedHierarchy.cs index f485afd8..f99fddb9 100644 --- a/src/ConsumeCsPreview/ClosedHierarchy.cs +++ b/src/ConsumeCsPreview/ClosedHierarchy.cs @@ -1,11 +1,13 @@ namespace ConsumeCsPreview; -/// -/// Compile-only coverage for the C# `closed` modifier. The compiler emits -/// IsClosedTypeAttribute on the closed type and -/// CompilerFeatureRequiredAttribute("ClosedClasses") on its constructors, -/// so this only compiles when both are polyfilled. -/// +// Compile-only coverage for the C# `closed` modifier. The compiler emits +// IsClosedTypeAttribute on the closed type and +// CompilerFeatureRequiredAttribute("ClosedClasses") on its constructors, +// so this only compiles when both are polyfilled. + +#region ClosedHierarchy + +// Only types in this file can derive from JobStatus closed class JobStatus; sealed class Queued : JobStatus; @@ -22,11 +24,8 @@ sealed class Failed(string error) : JobStatus static class ClosedHierarchy { - /// - /// No default arm: the switch is exhaustive because every direct descendant of the - /// closed is handled. Without exhaustiveness this warns CS8509, - /// which is an error since TreatWarningsAsErrors is enabled. - /// + // No default arm: the switch is exhaustive because every direct descendant of + // the closed JobStatus is handled. Without exhaustiveness this warns CS8509. public static string Describe(JobStatus status) => status switch { @@ -35,3 +34,5 @@ public static string Describe(JobStatus status) => Failed failed => $"failed: {failed.Error}" }; } + +#endregion