diff --git a/apiCount.include.md b/apiCount.include.md index 90cae835..670ee30b 100644 --- a/apiCount.include.md +++ b/apiCount.include.md @@ -1,28 +1,28 @@ -**API count: 1153** +**API count: 1155** ### Per Target Framework | Target | APIs | | -- | -- | -| `net461` | 1061 | -| `net462` | 1061 | -| `net47` | 1060 | -| `net471` | 1059 | -| `net472` | 1055 | -| `net48` | 1055 | -| `net481` | 1055 | -| `netstandard2.0` | 1057 | -| `netstandard2.1` | 890 | -| `netcoreapp2.0` | 980 | -| `netcoreapp2.1` | 901 | -| `netcoreapp2.2` | 901 | -| `netcoreapp3.0` | 862 | -| `netcoreapp3.1` | 861 | -| `net5.0` | 739 | -| `net6.0` | 635 | -| `net7.0` | 494 | -| `net8.0` | 373 | +| `net461` | 1063 | +| `net462` | 1063 | +| `net47` | 1062 | +| `net471` | 1061 | +| `net472` | 1057 | +| `net48` | 1057 | +| `net481` | 1057 | +| `netstandard2.0` | 1059 | +| `netstandard2.1` | 892 | +| `netcoreapp2.0` | 982 | +| `netcoreapp2.1` | 903 | +| `netcoreapp2.2` | 903 | +| `netcoreapp3.0` | 864 | +| `netcoreapp3.1` | 863 | +| `net5.0` | 741 | +| `net6.0` | 637 | +| `net7.0` | 496 | +| `net8.0` | 375 | | `net9.0` | 243 | | `net10.0` | 182 | | `net11.0` | 58 | -| `uap10.0` | 1047 | +| `uap10.0` | 1049 | diff --git a/api_list.include.md b/api_list.include.md index faa11269..96ef84de 100644 --- a/api_list.include.md +++ b/api_list.include.md @@ -494,6 +494,8 @@ * `bool TryFormat(Span, int, ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.guid.tryformat?view=net-11.0#system-guid-tryformat(system-span((system-byte))-system-int32@-system-readonlyspan((system-char)))) * `bool TryFormat(Span, int, ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.guid.tryformat?view=net-11.0#system-guid-tryformat(system-span((system-char))-system-int32@-system-readonlyspan((system-char)))) + * `int Variant` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.guid.variant?view=net-11.0) + * `int Version` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.guid.version?view=net-11.0) * `Guid CreateVersion7()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.guid.createversion7?view=net-11.0#system-guid-createversion7) * `Guid CreateVersion7(DateTimeOffset)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.guid.createversion7?view=net-11.0#system-guid-createversion7(system-datetimeoffset)) * `Guid Parse(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.guid.parse?view=net-11.0#system-guid-parse(system-readonlyspan((system-byte)))) diff --git a/assemblySize.include.md b/assemblySize.include.md index c9383394..29346deb 100644 --- a/assemblySize.include.md +++ b/assemblySize.include.md @@ -2,24 +2,24 @@ | | Empty Assembly | With Polyfill | Diff | Ensure | ArgumentExceptions | StringInterpolation | Nullability | |----------------|----------------|---------------|-----------|-----------|--------------------|---------------------|-------------| -| netstandard2.0 | 8.0KB | 384.0KB | +376.0KB | +8.5KB | +6.0KB | +8.5KB | +13.0KB | -| netstandard2.1 | 8.5KB | 339.5KB | +331.0KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | -| net461 | 8.5KB | 382.5KB | +374.0KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | -| net462 | 7.0KB | 386.0KB | +379.0KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | -| net47 | 7.0KB | 386.0KB | +379.0KB | +8.5KB | +6.5KB | +9.0KB | +13.5KB | -| net471 | 8.5KB | 385.0KB | +376.5KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | -| net472 | 8.5KB | 383.5KB | +375.0KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | -| net48 | 8.5KB | 383.5KB | +375.0KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | -| net481 | 8.5KB | 383.5KB | +375.0KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | -| netcoreapp2.0 | 9.0KB | 363.0KB | +354.0KB | +7.5KB | +5.0KB | +7.5KB | +12.0KB | -| netcoreapp2.1 | 9.0KB | 342.5KB | +333.5KB | +8.5KB | +6.0KB | +9.0KB | +13.5KB | -| netcoreapp2.2 | 9.0KB | 342.5KB | +333.5KB | +8.5KB | +6.5KB | +9.0KB | +13.5KB | -| netcoreapp3.0 | 9.5KB | 340.5KB | +331.0KB | +9.0KB | +6.5KB | +9.5KB | +14.0KB | -| netcoreapp3.1 | 9.5KB | 339.0KB | +329.5KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | -| net5.0 | 9.5KB | 304.5KB | +295.0KB | +9.0KB | +6.5KB | +9.0KB | +14.0KB | -| net6.0 | 10.0KB | 245.5KB | +235.5KB | +9.5KB | +7.0KB | +512bytes | +3.5KB | -| net7.0 | 10.0KB | 214.0KB | +204.0KB | +9.5KB | +6.0KB | +512bytes | +3.5KB | -| net8.0 | 9.5KB | 185.0KB | +175.5KB | +8.0KB | | +512bytes | +3.0KB | +| netstandard2.0 | 8.0KB | 384.0KB | +376.0KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | +| netstandard2.1 | 8.5KB | 340.0KB | +331.5KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | +| net461 | 8.5KB | 383.0KB | +374.5KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | +| net462 | 7.0KB | 386.5KB | +379.5KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | +| net47 | 7.0KB | 386.5KB | +379.5KB | +8.5KB | +6.0KB | +8.5KB | +13.0KB | +| net471 | 8.5KB | 385.5KB | +377.0KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | +| net472 | 8.5KB | 384.0KB | +375.5KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | +| net48 | 8.5KB | 384.0KB | +375.5KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | +| net481 | 8.5KB | 384.0KB | +375.5KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | +| netcoreapp2.0 | 9.0KB | 362.0KB | +353.0KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | +| netcoreapp2.1 | 9.0KB | 343.0KB | +334.0KB | +8.5KB | +6.5KB | +9.0KB | +13.5KB | +| netcoreapp2.2 | 9.0KB | 343.0KB | +334.0KB | +8.5KB | +6.5KB | +9.0KB | +13.5KB | +| netcoreapp3.0 | 9.5KB | 341.0KB | +331.5KB | +9.0KB | +6.5KB | +9.5KB | +14.0KB | +| netcoreapp3.1 | 9.5KB | 339.5KB | +330.0KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | +| net5.0 | 9.5KB | 305.0KB | +295.5KB | +9.0KB | +6.5KB | +9.0KB | +14.0KB | +| net6.0 | 10.0KB | 246.0KB | +236.0KB | +9.5KB | +7.0KB | +512bytes | +3.5KB | +| net7.0 | 10.0KB | 214.5KB | +204.5KB | +9.5KB | +6.0KB | +512bytes | +3.5KB | +| net8.0 | 9.5KB | 185.5KB | +176.0KB | +8.0KB | | +512bytes | +3.0KB | | net9.0 | 9.5KB | 117.0KB | +107.5KB | +8.0KB | | +512bytes | +3.0KB | | net10.0 | 10.0KB | 93.5KB | +83.5KB | +8.5KB | | +512bytes | +3.0KB | | 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 | 559.0KB | +551.0KB | +16.2KB | +7.7KB | +13.4KB | +18.4KB | -| netstandard2.1 | 8.5KB | 487.5KB | +479.0KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | -| net461 | 8.5KB | 558.6KB | +550.1KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | -| net462 | 7.0KB | 562.1KB | +555.1KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | -| net47 | 7.0KB | 561.8KB | +554.8KB | +16.2KB | +8.2KB | +13.9KB | +18.9KB | -| net471 | 8.5KB | 560.5KB | +552.0KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | -| net472 | 8.5KB | 557.9KB | +549.4KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | -| net48 | 8.5KB | 557.9KB | +549.4KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | -| net481 | 8.5KB | 557.9KB | +549.4KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | -| netcoreapp2.0 | 9.0KB | 527.5KB | +518.5KB | +15.2KB | +6.7KB | +12.4KB | +17.4KB | -| netcoreapp2.1 | 9.0KB | 494.2KB | +485.2KB | +16.2KB | +7.7KB | +13.9KB | +18.9KB | -| netcoreapp2.2 | 9.0KB | 494.2KB | +485.2KB | +16.2KB | +8.2KB | +13.9KB | +18.9KB | -| netcoreapp3.0 | 9.5KB | 485.6KB | +476.1KB | +16.7KB | +8.2KB | +14.4KB | +19.4KB | -| netcoreapp3.1 | 9.5KB | 484.0KB | +474.5KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | -| net5.0 | 9.5KB | 432.1KB | +422.6KB | +16.7KB | +8.2KB | +13.9KB | +19.4KB | -| net6.0 | 10.0KB | 352.9KB | +342.9KB | +17.2KB | +8.7KB | +1.1KB | +4.2KB | -| net7.0 | 10.0KB | 304.6KB | +294.6KB | +17.1KB | +7.4KB | +1.1KB | +4.2KB | -| net8.0 | 9.5KB | 261.8KB | +252.3KB | +15.5KB | +299bytes | +1.1KB | +3.7KB | +| netstandard2.0 | 8.0KB | 559.3KB | +551.3KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | +| netstandard2.1 | 8.5KB | 488.3KB | +479.8KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | +| net461 | 8.5KB | 559.3KB | +550.8KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | +| net462 | 7.0KB | 562.8KB | +555.8KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | +| net47 | 7.0KB | 562.6KB | +555.6KB | +16.2KB | +7.7KB | +13.4KB | +18.4KB | +| net471 | 8.5KB | 561.2KB | +552.7KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | +| net472 | 8.5KB | 558.6KB | +550.1KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | +| net48 | 8.5KB | 558.6KB | +550.1KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | +| net481 | 8.5KB | 558.6KB | +550.1KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | +| netcoreapp2.0 | 9.0KB | 526.7KB | +517.7KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | +| netcoreapp2.1 | 9.0KB | 495.0KB | +486.0KB | +16.2KB | +8.2KB | +13.9KB | +18.9KB | +| netcoreapp2.2 | 9.0KB | 495.0KB | +486.0KB | +16.2KB | +8.2KB | +13.9KB | +18.9KB | +| netcoreapp3.0 | 9.5KB | 486.4KB | +476.9KB | +16.7KB | +8.2KB | +14.4KB | +19.4KB | +| netcoreapp3.1 | 9.5KB | 484.8KB | +475.3KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | +| net5.0 | 9.5KB | 432.9KB | +423.4KB | +16.7KB | +8.2KB | +13.9KB | +19.4KB | +| net6.0 | 10.0KB | 353.7KB | +343.7KB | +17.2KB | +8.7KB | +1.1KB | +4.2KB | +| net7.0 | 10.0KB | 305.4KB | +295.4KB | +17.1KB | +7.4KB | +1.1KB | +4.2KB | +| net8.0 | 9.5KB | 262.6KB | +253.1KB | +15.5KB | +299bytes | +1.1KB | +3.7KB | | net9.0 | 9.5KB | 169.1KB | +159.6KB | +15.5KB | | +1.1KB | +3.7KB | | net10.0 | 10.0KB | 136.1KB | +126.1KB | +16.0KB | | +1.1KB | +3.7KB | | net11.0 | 10.0KB | 30.9KB | +20.9KB | +16.5KB | | +1.1KB | +4.2KB | diff --git a/readme.md b/readme.md index c602df7c..4f10402b 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: 1153** +**API count: 1155** ### Per Target Framework | Target | APIs | | -- | -- | -| `net461` | 1061 | -| `net462` | 1061 | -| `net47` | 1060 | -| `net471` | 1059 | -| `net472` | 1055 | -| `net48` | 1055 | -| `net481` | 1055 | -| `netstandard2.0` | 1057 | -| `netstandard2.1` | 890 | -| `netcoreapp2.0` | 980 | -| `netcoreapp2.1` | 901 | -| `netcoreapp2.2` | 901 | -| `netcoreapp3.0` | 862 | -| `netcoreapp3.1` | 861 | -| `net5.0` | 739 | -| `net6.0` | 635 | -| `net7.0` | 494 | -| `net8.0` | 373 | +| `net461` | 1063 | +| `net462` | 1063 | +| `net47` | 1062 | +| `net471` | 1061 | +| `net472` | 1057 | +| `net48` | 1057 | +| `net481` | 1057 | +| `netstandard2.0` | 1059 | +| `netstandard2.1` | 892 | +| `netcoreapp2.0` | 982 | +| `netcoreapp2.1` | 903 | +| `netcoreapp2.2` | 903 | +| `netcoreapp3.0` | 864 | +| `netcoreapp3.1` | 863 | +| `net5.0` | 741 | +| `net6.0` | 637 | +| `net7.0` | 496 | +| `net8.0` | 375 | | `net9.0` | 243 | | `net10.0` | 182 | | `net11.0` | 58 | -| `uap10.0` | 1047 | +| `uap10.0` | 1049 | @@ -96,24 +96,24 @@ 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 | 384.0KB | +376.0KB | +8.5KB | +6.0KB | +8.5KB | +13.0KB | -| netstandard2.1 | 8.5KB | 339.5KB | +331.0KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | -| net461 | 8.5KB | 382.5KB | +374.0KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | -| net462 | 7.0KB | 386.0KB | +379.0KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | -| net47 | 7.0KB | 386.0KB | +379.0KB | +8.5KB | +6.5KB | +9.0KB | +13.5KB | -| net471 | 8.5KB | 385.0KB | +376.5KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | -| net472 | 8.5KB | 383.5KB | +375.0KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | -| net48 | 8.5KB | 383.5KB | +375.0KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | -| net481 | 8.5KB | 383.5KB | +375.0KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | -| netcoreapp2.0 | 9.0KB | 363.0KB | +354.0KB | +7.5KB | +5.0KB | +7.5KB | +12.0KB | -| netcoreapp2.1 | 9.0KB | 342.5KB | +333.5KB | +8.5KB | +6.0KB | +9.0KB | +13.5KB | -| netcoreapp2.2 | 9.0KB | 342.5KB | +333.5KB | +8.5KB | +6.5KB | +9.0KB | +13.5KB | -| netcoreapp3.0 | 9.5KB | 340.5KB | +331.0KB | +9.0KB | +6.5KB | +9.5KB | +14.0KB | -| netcoreapp3.1 | 9.5KB | 339.0KB | +329.5KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | -| net5.0 | 9.5KB | 304.5KB | +295.0KB | +9.0KB | +6.5KB | +9.0KB | +14.0KB | -| net6.0 | 10.0KB | 245.5KB | +235.5KB | +9.5KB | +7.0KB | +512bytes | +3.5KB | -| net7.0 | 10.0KB | 214.0KB | +204.0KB | +9.5KB | +6.0KB | +512bytes | +3.5KB | -| net8.0 | 9.5KB | 185.0KB | +175.5KB | +8.0KB | | +512bytes | +3.0KB | +| netstandard2.0 | 8.0KB | 384.0KB | +376.0KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | +| netstandard2.1 | 8.5KB | 340.0KB | +331.5KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | +| net461 | 8.5KB | 383.0KB | +374.5KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | +| net462 | 7.0KB | 386.5KB | +379.5KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | +| net47 | 7.0KB | 386.5KB | +379.5KB | +8.5KB | +6.0KB | +8.5KB | +13.0KB | +| net471 | 8.5KB | 385.5KB | +377.0KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | +| net472 | 8.5KB | 384.0KB | +375.5KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | +| net48 | 8.5KB | 384.0KB | +375.5KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | +| net481 | 8.5KB | 384.0KB | +375.5KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | +| netcoreapp2.0 | 9.0KB | 362.0KB | +353.0KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | +| netcoreapp2.1 | 9.0KB | 343.0KB | +334.0KB | +8.5KB | +6.5KB | +9.0KB | +13.5KB | +| netcoreapp2.2 | 9.0KB | 343.0KB | +334.0KB | +8.5KB | +6.5KB | +9.0KB | +13.5KB | +| netcoreapp3.0 | 9.5KB | 341.0KB | +331.5KB | +9.0KB | +6.5KB | +9.5KB | +14.0KB | +| netcoreapp3.1 | 9.5KB | 339.5KB | +330.0KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | +| net5.0 | 9.5KB | 305.0KB | +295.5KB | +9.0KB | +6.5KB | +9.0KB | +14.0KB | +| net6.0 | 10.0KB | 246.0KB | +236.0KB | +9.5KB | +7.0KB | +512bytes | +3.5KB | +| net7.0 | 10.0KB | 214.5KB | +204.5KB | +9.5KB | +6.0KB | +512bytes | +3.5KB | +| net8.0 | 9.5KB | 185.5KB | +176.0KB | +8.0KB | | +512bytes | +3.0KB | | net9.0 | 9.5KB | 117.0KB | +107.5KB | +8.0KB | | +512bytes | +3.0KB | | net10.0 | 10.0KB | 93.5KB | +83.5KB | +8.5KB | | +512bytes | +3.0KB | | net11.0 | 10.0KB | 21.0KB | +11.0KB | +9.0KB | | +512bytes | +3.5KB | @@ -123,24 +123,24 @@ 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 | 559.0KB | +551.0KB | +16.2KB | +7.7KB | +13.4KB | +18.4KB | -| netstandard2.1 | 8.5KB | 487.5KB | +479.0KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | -| net461 | 8.5KB | 558.6KB | +550.1KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | -| net462 | 7.0KB | 562.1KB | +555.1KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | -| net47 | 7.0KB | 561.8KB | +554.8KB | +16.2KB | +8.2KB | +13.9KB | +18.9KB | -| net471 | 8.5KB | 560.5KB | +552.0KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | -| net472 | 8.5KB | 557.9KB | +549.4KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | -| net48 | 8.5KB | 557.9KB | +549.4KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | -| net481 | 8.5KB | 557.9KB | +549.4KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | -| netcoreapp2.0 | 9.0KB | 527.5KB | +518.5KB | +15.2KB | +6.7KB | +12.4KB | +17.4KB | -| netcoreapp2.1 | 9.0KB | 494.2KB | +485.2KB | +16.2KB | +7.7KB | +13.9KB | +18.9KB | -| netcoreapp2.2 | 9.0KB | 494.2KB | +485.2KB | +16.2KB | +8.2KB | +13.9KB | +18.9KB | -| netcoreapp3.0 | 9.5KB | 485.6KB | +476.1KB | +16.7KB | +8.2KB | +14.4KB | +19.4KB | -| netcoreapp3.1 | 9.5KB | 484.0KB | +474.5KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | -| net5.0 | 9.5KB | 432.1KB | +422.6KB | +16.7KB | +8.2KB | +13.9KB | +19.4KB | -| net6.0 | 10.0KB | 352.9KB | +342.9KB | +17.2KB | +8.7KB | +1.1KB | +4.2KB | -| net7.0 | 10.0KB | 304.6KB | +294.6KB | +17.1KB | +7.4KB | +1.1KB | +4.2KB | -| net8.0 | 9.5KB | 261.8KB | +252.3KB | +15.5KB | +299bytes | +1.1KB | +3.7KB | +| netstandard2.0 | 8.0KB | 559.3KB | +551.3KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | +| netstandard2.1 | 8.5KB | 488.3KB | +479.8KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | +| net461 | 8.5KB | 559.3KB | +550.8KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | +| net462 | 7.0KB | 562.8KB | +555.8KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | +| net47 | 7.0KB | 562.6KB | +555.6KB | +16.2KB | +7.7KB | +13.4KB | +18.4KB | +| net471 | 8.5KB | 561.2KB | +552.7KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | +| net472 | 8.5KB | 558.6KB | +550.1KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | +| net48 | 8.5KB | 558.6KB | +550.1KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | +| net481 | 8.5KB | 558.6KB | +550.1KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | +| netcoreapp2.0 | 9.0KB | 526.7KB | +517.7KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | +| netcoreapp2.1 | 9.0KB | 495.0KB | +486.0KB | +16.2KB | +8.2KB | +13.9KB | +18.9KB | +| netcoreapp2.2 | 9.0KB | 495.0KB | +486.0KB | +16.2KB | +8.2KB | +13.9KB | +18.9KB | +| netcoreapp3.0 | 9.5KB | 486.4KB | +476.9KB | +16.7KB | +8.2KB | +14.4KB | +19.4KB | +| netcoreapp3.1 | 9.5KB | 484.8KB | +475.3KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | +| net5.0 | 9.5KB | 432.9KB | +423.4KB | +16.7KB | +8.2KB | +13.9KB | +19.4KB | +| net6.0 | 10.0KB | 353.7KB | +343.7KB | +17.2KB | +8.7KB | +1.1KB | +4.2KB | +| net7.0 | 10.0KB | 305.4KB | +295.4KB | +17.1KB | +7.4KB | +1.1KB | +4.2KB | +| net8.0 | 9.5KB | 262.6KB | +253.1KB | +15.5KB | +299bytes | +1.1KB | +3.7KB | | net9.0 | 9.5KB | 169.1KB | +159.6KB | +15.5KB | | +1.1KB | +3.7KB | | net10.0 | 10.0KB | 136.1KB | +126.1KB | +16.0KB | | +1.1KB | +3.7KB | | net11.0 | 10.0KB | 30.9KB | +20.9KB | +16.5KB | | +1.1KB | +4.2KB | @@ -1109,6 +1109,8 @@ The class `Polyfill` includes the following extension methods: * `bool TryFormat(Span, int, ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.guid.tryformat?view=net-11.0#system-guid-tryformat(system-span((system-byte))-system-int32@-system-readonlyspan((system-char)))) * `bool TryFormat(Span, int, ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.guid.tryformat?view=net-11.0#system-guid-tryformat(system-span((system-char))-system-int32@-system-readonlyspan((system-char)))) + * `int Variant` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.guid.variant?view=net-11.0) + * `int Version` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.guid.version?view=net-11.0) * `Guid CreateVersion7()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.guid.createversion7?view=net-11.0#system-guid-createversion7) * `Guid CreateVersion7(DateTimeOffset)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.guid.createversion7?view=net-11.0#system-guid-createversion7(system-datetimeoffset)) * `Guid Parse(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.guid.parse?view=net-11.0#system-guid-parse(system-readonlyspan((system-byte)))) @@ -2568,7 +2570,7 @@ void ObjectDisposedExceptionExample(bool isDisposed) ObjectDisposedException.ThrowIf(isDisposed, typeof(Consume)); } ``` -snippet source | anchor +snippet source | anchor @@ -2587,7 +2589,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 4fd2d0e5..68142a3c 100644 --- a/src/Consume/Consume.cs +++ b/src/Consume/Consume.cs @@ -204,6 +204,8 @@ void GuidUsage() { var guid = Guid.CreateVersion7(); guid = Guid.CreateVersion7(timestamp: DateTimeOffset.UtcNow); + var variant = guid.Variant; + var version = guid.Version; var result = Guid.TryParse(s: "", provider: null, result: out guid); #if FeatureMemory ReadOnlySpan byteSpan = default; diff --git a/src/Polyfill/Polyfill_Guid.cs b/src/Polyfill/Polyfill_Guid.cs new file mode 100644 index 00000000..c2dff712 --- /dev/null +++ b/src/Polyfill/Polyfill_Guid.cs @@ -0,0 +1,42 @@ +#pragma warning disable + +#if !NET9_0_OR_GREATER + +namespace Polyfills; + +using System; + +static partial class Polyfill +{ + extension(Guid target) + { + /// + /// Gets the variant field of the . + /// + //Link: https://learn.microsoft.com/en-us/dotnet/api/system.guid.variant?view=net-11.0 + public int Variant => + HighNibble(target, 8); + + /// + /// Gets the version field of the . + /// + //Link: https://learn.microsoft.com/en-us/dotnet/api/system.guid.version?view=net-11.0 + public int Version => + HighNibble(target, 7); + } + + // Both fields are the high nibble of a single byte of the little endian layout that + // ToByteArray and TryWriteBytes produce: the version at index 7 and the variant at index 8. + static int HighNibble(Guid value, int index) + { +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + Span buffer = stackalloc byte[16]; + value.TryWriteBytes(buffer); + return buffer[index] >> 4; +#else + return value.ToByteArray()[index] >> 4; +#endif + } +} + +#endif diff --git a/src/Split/net461/Polyfill_Guid.cs b/src/Split/net461/Polyfill_Guid.cs new file mode 100644 index 00000000..604d6253 --- /dev/null +++ b/src/Split/net461/Polyfill_Guid.cs @@ -0,0 +1,25 @@ +// +#pragma warning disable +#pragma warning disable +namespace Polyfills; +using System; +static partial class Polyfill +{ + extension(Guid target) + { + /// + /// Gets the variant field of the . + /// + public int Variant => + HighNibble(target, 8); + /// + /// Gets the version field of the . + /// + public int Version => + HighNibble(target, 7); + } + static int HighNibble(Guid value, int index) + { + return value.ToByteArray()[index] >> 4; + } +} diff --git a/src/Split/net462/Polyfill_Guid.cs b/src/Split/net462/Polyfill_Guid.cs new file mode 100644 index 00000000..604d6253 --- /dev/null +++ b/src/Split/net462/Polyfill_Guid.cs @@ -0,0 +1,25 @@ +// +#pragma warning disable +#pragma warning disable +namespace Polyfills; +using System; +static partial class Polyfill +{ + extension(Guid target) + { + /// + /// Gets the variant field of the . + /// + public int Variant => + HighNibble(target, 8); + /// + /// Gets the version field of the . + /// + public int Version => + HighNibble(target, 7); + } + static int HighNibble(Guid value, int index) + { + return value.ToByteArray()[index] >> 4; + } +} diff --git a/src/Split/net47/Polyfill_Guid.cs b/src/Split/net47/Polyfill_Guid.cs new file mode 100644 index 00000000..604d6253 --- /dev/null +++ b/src/Split/net47/Polyfill_Guid.cs @@ -0,0 +1,25 @@ +// +#pragma warning disable +#pragma warning disable +namespace Polyfills; +using System; +static partial class Polyfill +{ + extension(Guid target) + { + /// + /// Gets the variant field of the . + /// + public int Variant => + HighNibble(target, 8); + /// + /// Gets the version field of the . + /// + public int Version => + HighNibble(target, 7); + } + static int HighNibble(Guid value, int index) + { + return value.ToByteArray()[index] >> 4; + } +} diff --git a/src/Split/net471/Polyfill_Guid.cs b/src/Split/net471/Polyfill_Guid.cs new file mode 100644 index 00000000..604d6253 --- /dev/null +++ b/src/Split/net471/Polyfill_Guid.cs @@ -0,0 +1,25 @@ +// +#pragma warning disable +#pragma warning disable +namespace Polyfills; +using System; +static partial class Polyfill +{ + extension(Guid target) + { + /// + /// Gets the variant field of the . + /// + public int Variant => + HighNibble(target, 8); + /// + /// Gets the version field of the . + /// + public int Version => + HighNibble(target, 7); + } + static int HighNibble(Guid value, int index) + { + return value.ToByteArray()[index] >> 4; + } +} diff --git a/src/Split/net472/Polyfill_Guid.cs b/src/Split/net472/Polyfill_Guid.cs new file mode 100644 index 00000000..604d6253 --- /dev/null +++ b/src/Split/net472/Polyfill_Guid.cs @@ -0,0 +1,25 @@ +// +#pragma warning disable +#pragma warning disable +namespace Polyfills; +using System; +static partial class Polyfill +{ + extension(Guid target) + { + /// + /// Gets the variant field of the . + /// + public int Variant => + HighNibble(target, 8); + /// + /// Gets the version field of the . + /// + public int Version => + HighNibble(target, 7); + } + static int HighNibble(Guid value, int index) + { + return value.ToByteArray()[index] >> 4; + } +} diff --git a/src/Split/net48/Polyfill_Guid.cs b/src/Split/net48/Polyfill_Guid.cs new file mode 100644 index 00000000..604d6253 --- /dev/null +++ b/src/Split/net48/Polyfill_Guid.cs @@ -0,0 +1,25 @@ +// +#pragma warning disable +#pragma warning disable +namespace Polyfills; +using System; +static partial class Polyfill +{ + extension(Guid target) + { + /// + /// Gets the variant field of the . + /// + public int Variant => + HighNibble(target, 8); + /// + /// Gets the version field of the . + /// + public int Version => + HighNibble(target, 7); + } + static int HighNibble(Guid value, int index) + { + return value.ToByteArray()[index] >> 4; + } +} diff --git a/src/Split/net481/Polyfill_Guid.cs b/src/Split/net481/Polyfill_Guid.cs new file mode 100644 index 00000000..604d6253 --- /dev/null +++ b/src/Split/net481/Polyfill_Guid.cs @@ -0,0 +1,25 @@ +// +#pragma warning disable +#pragma warning disable +namespace Polyfills; +using System; +static partial class Polyfill +{ + extension(Guid target) + { + /// + /// Gets the variant field of the . + /// + public int Variant => + HighNibble(target, 8); + /// + /// Gets the version field of the . + /// + public int Version => + HighNibble(target, 7); + } + static int HighNibble(Guid value, int index) + { + return value.ToByteArray()[index] >> 4; + } +} diff --git a/src/Split/net5.0/Polyfill_Guid.cs b/src/Split/net5.0/Polyfill_Guid.cs new file mode 100644 index 00000000..5fea935f --- /dev/null +++ b/src/Split/net5.0/Polyfill_Guid.cs @@ -0,0 +1,27 @@ +// +#pragma warning disable +#pragma warning disable +namespace Polyfills; +using System; +static partial class Polyfill +{ + extension(Guid target) + { + /// + /// Gets the variant field of the . + /// + public int Variant => + HighNibble(target, 8); + /// + /// Gets the version field of the . + /// + public int Version => + HighNibble(target, 7); + } + static int HighNibble(Guid value, int index) + { + Span buffer = stackalloc byte[16]; + value.TryWriteBytes(buffer); + return buffer[index] >> 4; + } +} diff --git a/src/Split/net6.0/Polyfill_Guid.cs b/src/Split/net6.0/Polyfill_Guid.cs new file mode 100644 index 00000000..5fea935f --- /dev/null +++ b/src/Split/net6.0/Polyfill_Guid.cs @@ -0,0 +1,27 @@ +// +#pragma warning disable +#pragma warning disable +namespace Polyfills; +using System; +static partial class Polyfill +{ + extension(Guid target) + { + /// + /// Gets the variant field of the . + /// + public int Variant => + HighNibble(target, 8); + /// + /// Gets the version field of the . + /// + public int Version => + HighNibble(target, 7); + } + static int HighNibble(Guid value, int index) + { + Span buffer = stackalloc byte[16]; + value.TryWriteBytes(buffer); + return buffer[index] >> 4; + } +} diff --git a/src/Split/net7.0/Polyfill_Guid.cs b/src/Split/net7.0/Polyfill_Guid.cs new file mode 100644 index 00000000..5fea935f --- /dev/null +++ b/src/Split/net7.0/Polyfill_Guid.cs @@ -0,0 +1,27 @@ +// +#pragma warning disable +#pragma warning disable +namespace Polyfills; +using System; +static partial class Polyfill +{ + extension(Guid target) + { + /// + /// Gets the variant field of the . + /// + public int Variant => + HighNibble(target, 8); + /// + /// Gets the version field of the . + /// + public int Version => + HighNibble(target, 7); + } + static int HighNibble(Guid value, int index) + { + Span buffer = stackalloc byte[16]; + value.TryWriteBytes(buffer); + return buffer[index] >> 4; + } +} diff --git a/src/Split/net8.0/Polyfill_Guid.cs b/src/Split/net8.0/Polyfill_Guid.cs new file mode 100644 index 00000000..5fea935f --- /dev/null +++ b/src/Split/net8.0/Polyfill_Guid.cs @@ -0,0 +1,27 @@ +// +#pragma warning disable +#pragma warning disable +namespace Polyfills; +using System; +static partial class Polyfill +{ + extension(Guid target) + { + /// + /// Gets the variant field of the . + /// + public int Variant => + HighNibble(target, 8); + /// + /// Gets the version field of the . + /// + public int Version => + HighNibble(target, 7); + } + static int HighNibble(Guid value, int index) + { + Span buffer = stackalloc byte[16]; + value.TryWriteBytes(buffer); + return buffer[index] >> 4; + } +} diff --git a/src/Split/netcoreapp2.0/Polyfill_Guid.cs b/src/Split/netcoreapp2.0/Polyfill_Guid.cs new file mode 100644 index 00000000..604d6253 --- /dev/null +++ b/src/Split/netcoreapp2.0/Polyfill_Guid.cs @@ -0,0 +1,25 @@ +// +#pragma warning disable +#pragma warning disable +namespace Polyfills; +using System; +static partial class Polyfill +{ + extension(Guid target) + { + /// + /// Gets the variant field of the . + /// + public int Variant => + HighNibble(target, 8); + /// + /// Gets the version field of the . + /// + public int Version => + HighNibble(target, 7); + } + static int HighNibble(Guid value, int index) + { + return value.ToByteArray()[index] >> 4; + } +} diff --git a/src/Split/netcoreapp2.1/Polyfill_Guid.cs b/src/Split/netcoreapp2.1/Polyfill_Guid.cs new file mode 100644 index 00000000..5fea935f --- /dev/null +++ b/src/Split/netcoreapp2.1/Polyfill_Guid.cs @@ -0,0 +1,27 @@ +// +#pragma warning disable +#pragma warning disable +namespace Polyfills; +using System; +static partial class Polyfill +{ + extension(Guid target) + { + /// + /// Gets the variant field of the . + /// + public int Variant => + HighNibble(target, 8); + /// + /// Gets the version field of the . + /// + public int Version => + HighNibble(target, 7); + } + static int HighNibble(Guid value, int index) + { + Span buffer = stackalloc byte[16]; + value.TryWriteBytes(buffer); + return buffer[index] >> 4; + } +} diff --git a/src/Split/netcoreapp2.2/Polyfill_Guid.cs b/src/Split/netcoreapp2.2/Polyfill_Guid.cs new file mode 100644 index 00000000..5fea935f --- /dev/null +++ b/src/Split/netcoreapp2.2/Polyfill_Guid.cs @@ -0,0 +1,27 @@ +// +#pragma warning disable +#pragma warning disable +namespace Polyfills; +using System; +static partial class Polyfill +{ + extension(Guid target) + { + /// + /// Gets the variant field of the . + /// + public int Variant => + HighNibble(target, 8); + /// + /// Gets the version field of the . + /// + public int Version => + HighNibble(target, 7); + } + static int HighNibble(Guid value, int index) + { + Span buffer = stackalloc byte[16]; + value.TryWriteBytes(buffer); + return buffer[index] >> 4; + } +} diff --git a/src/Split/netcoreapp3.0/Polyfill_Guid.cs b/src/Split/netcoreapp3.0/Polyfill_Guid.cs new file mode 100644 index 00000000..5fea935f --- /dev/null +++ b/src/Split/netcoreapp3.0/Polyfill_Guid.cs @@ -0,0 +1,27 @@ +// +#pragma warning disable +#pragma warning disable +namespace Polyfills; +using System; +static partial class Polyfill +{ + extension(Guid target) + { + /// + /// Gets the variant field of the . + /// + public int Variant => + HighNibble(target, 8); + /// + /// Gets the version field of the . + /// + public int Version => + HighNibble(target, 7); + } + static int HighNibble(Guid value, int index) + { + Span buffer = stackalloc byte[16]; + value.TryWriteBytes(buffer); + return buffer[index] >> 4; + } +} diff --git a/src/Split/netcoreapp3.1/Polyfill_Guid.cs b/src/Split/netcoreapp3.1/Polyfill_Guid.cs new file mode 100644 index 00000000..5fea935f --- /dev/null +++ b/src/Split/netcoreapp3.1/Polyfill_Guid.cs @@ -0,0 +1,27 @@ +// +#pragma warning disable +#pragma warning disable +namespace Polyfills; +using System; +static partial class Polyfill +{ + extension(Guid target) + { + /// + /// Gets the variant field of the . + /// + public int Variant => + HighNibble(target, 8); + /// + /// Gets the version field of the . + /// + public int Version => + HighNibble(target, 7); + } + static int HighNibble(Guid value, int index) + { + Span buffer = stackalloc byte[16]; + value.TryWriteBytes(buffer); + return buffer[index] >> 4; + } +} diff --git a/src/Split/netstandard2.0/Polyfill_Guid.cs b/src/Split/netstandard2.0/Polyfill_Guid.cs new file mode 100644 index 00000000..604d6253 --- /dev/null +++ b/src/Split/netstandard2.0/Polyfill_Guid.cs @@ -0,0 +1,25 @@ +// +#pragma warning disable +#pragma warning disable +namespace Polyfills; +using System; +static partial class Polyfill +{ + extension(Guid target) + { + /// + /// Gets the variant field of the . + /// + public int Variant => + HighNibble(target, 8); + /// + /// Gets the version field of the . + /// + public int Version => + HighNibble(target, 7); + } + static int HighNibble(Guid value, int index) + { + return value.ToByteArray()[index] >> 4; + } +} diff --git a/src/Split/netstandard2.1/Polyfill_Guid.cs b/src/Split/netstandard2.1/Polyfill_Guid.cs new file mode 100644 index 00000000..5fea935f --- /dev/null +++ b/src/Split/netstandard2.1/Polyfill_Guid.cs @@ -0,0 +1,27 @@ +// +#pragma warning disable +#pragma warning disable +namespace Polyfills; +using System; +static partial class Polyfill +{ + extension(Guid target) + { + /// + /// Gets the variant field of the . + /// + public int Variant => + HighNibble(target, 8); + /// + /// Gets the version field of the . + /// + public int Version => + HighNibble(target, 7); + } + static int HighNibble(Guid value, int index) + { + Span buffer = stackalloc byte[16]; + value.TryWriteBytes(buffer); + return buffer[index] >> 4; + } +} diff --git a/src/Split/uap10.0/Polyfill_Guid.cs b/src/Split/uap10.0/Polyfill_Guid.cs new file mode 100644 index 00000000..604d6253 --- /dev/null +++ b/src/Split/uap10.0/Polyfill_Guid.cs @@ -0,0 +1,25 @@ +// +#pragma warning disable +#pragma warning disable +namespace Polyfills; +using System; +static partial class Polyfill +{ + extension(Guid target) + { + /// + /// Gets the variant field of the . + /// + public int Variant => + HighNibble(target, 8); + /// + /// Gets the version field of the . + /// + public int Version => + HighNibble(target, 7); + } + static int HighNibble(Guid value, int index) + { + return value.ToByteArray()[index] >> 4; + } +} diff --git a/src/Tests/GuidVariantTests.cs b/src/Tests/GuidVariantTests.cs new file mode 100644 index 00000000..9bbe9df7 --- /dev/null +++ b/src/Tests/GuidVariantTests.cs @@ -0,0 +1,122 @@ +// Runs on every target, so net9.0 and later validate the BCL and everything below the polyfill. +public class GuidVariantTests +{ + // Both fields are exhaustively determined by two bytes, so every combination is checked + // rather than sampled. + [Test] + public async Task ExhaustiveOverBothBytes() + { + var failures = 0; + var visited = 0; + for (var seven = 0; seven < 256; seven++) + for (var eight = 0; eight < 256; eight++) + { + var bytes = new byte[16]; + bytes[7] = (byte) seven; + bytes[8] = (byte) eight; + var guid = new Guid(bytes); + + visited++; + if (guid.Version != seven >> 4 || + guid.Variant != eight >> 4) + { + failures++; + } + } + + await Assert.That(failures).IsEqualTo(0); + await Assert.That(visited).IsEqualTo(65536); + } + + // the other fourteen bytes must not affect either value + [Test] + public async Task OtherBytesAreIgnored() + { + var random = new Random(42); + var failures = 0; + for (var i = 0; i < 20000; i++) + { + var bytes = new byte[16]; + random.NextBytes(bytes); + bytes[7] = 0x74; + bytes[8] = 0xb9; + var guid = new Guid(bytes); + + if (guid.Version != 7 || + guid.Variant != 11) + { + failures++; + } + } + + await Assert.That(failures).IsEqualTo(0); + } + + [Test] + public async Task KnownUuids() + { + // the DNS namespace uuid from RFC 4122, a version 1 uuid + await Assert.That(Guid.Parse("6ba7b810-9dad-11d1-80b4-00c04fd430c8").Version).IsEqualTo(1); + await Assert.That(Guid.Parse("6ba7b810-9dad-11d1-80b4-00c04fd430c8").Variant).IsEqualTo(8); + + // a version 3, name based + await Assert.That(Guid.Parse("3d813cbb-47fb-32ba-91df-831e1593ac29").Version).IsEqualTo(3); + await Assert.That(Guid.Parse("3d813cbb-47fb-32ba-91df-831e1593ac29").Variant).IsEqualTo(9); + + // a version 7, time ordered + await Assert.That(Guid.Parse("01890a5d-ac96-774b-bcce-b302099a8057").Version).IsEqualTo(7); + await Assert.That(Guid.Parse("01890a5d-ac96-774b-bcce-b302099a8057").Variant).IsEqualTo(11); + + await Assert.That(Guid.Empty.Version).IsEqualTo(0); + await Assert.That(Guid.Empty.Variant).IsEqualTo(0); + + var allBitsSet = Guid.Parse("ffffffff-ffff-ffff-ffff-ffffffffffff"); + await Assert.That(allBitsSet.Version).IsEqualTo(15); + await Assert.That(allBitsSet.Variant).IsEqualTo(15); + } + + // Variant is the raw high nibble of byte 8, not the RFC 4122 variant field, which is only the + // top two bits. So an RFC 4122 uuid reports 8, 9, 10 or 11 rather than one fixed number. + [Test] + public async Task GeneratedGuids() + { + for (var i = 0; i < 2000; i++) + { + var random = Guid.NewGuid(); + await Assert.That(random.Version).IsEqualTo(4); + await Assert.That(random.Variant & 0b1100).IsEqualTo(0b1000); + + var seven = Guid.CreateVersion7(); + await Assert.That(seven.Version).IsEqualTo(7); + await Assert.That(seven.Variant & 0b1100).IsEqualTo(0b1000); + } + } + + // the value comes from the same byte the string form shows, which is the check that would + // catch reading the wrong index or the wrong endianness of the third group + [Test] + public async Task AgreesWithTheStringForm() + { + var random = new Random(7); + var failures = 0; + for (var i = 0; i < 20000; i++) + { + var bytes = new byte[16]; + random.NextBytes(bytes); + var guid = new Guid(bytes); + var text = guid.ToString("D"); + + // "xxxxxxxx-xxxx-Vxxx-Nxxx-xxxxxxxxxxxx" + var version = Convert.ToInt32(text.Substring(14, 1), 16); + var variant = Convert.ToInt32(text.Substring(19, 1), 16); + + if (guid.Version != version || + guid.Variant != variant) + { + failures++; + } + } + + await Assert.That(failures).IsEqualTo(0); + } +}