Remove langcode from MSDN links
parent
cdd4703eb2
commit
e39f8ab984
|
@ -9,26 +9,26 @@ Under .NET 8 (all of this is untested, just based on the docs and .NET issue tra
|
||||||
- The largest 1D byte array is `new byte[Array.MaxLength]`, `Array.MaxLength` being [hardcoded to `0x7FFF_FFC7`](https://github.com/dotnet/runtime/blob/5535e31a712343a63f5d7d796cd874e563e5ac14/src/libraries/System.Private.CoreLib/src/System/Array.cs#L2135-L2137) or just under 2 GiB. (Would probably want to alloc in 1 GiB chunks to have nice code, maybe even smaller to keep the GC happy.)
|
- The largest 1D byte array is `new byte[Array.MaxLength]`, `Array.MaxLength` being [hardcoded to `0x7FFF_FFC7`](https://github.com/dotnet/runtime/blob/5535e31a712343a63f5d7d796cd874e563e5ac14/src/libraries/System.Private.CoreLib/src/System/Array.cs#L2135-L2137) or just under 2 GiB. (Would probably want to alloc in 1 GiB chunks to have nice code, maybe even smaller to keep the GC happy.)
|
||||||
- The largest 1D struct array is `new T[Array.MaxLength]`. So its size is... unbounded since structs don't have a size limit apart from the stack size (and `[InlineArray]`'s poorly-documented 1 MiB cap). (TODO check there isn't an undocumented cap on struct size)
|
- The largest 1D struct array is `new T[Array.MaxLength]`. So its size is... unbounded since structs don't have a size limit apart from the stack size (and `[InlineArray]`'s poorly-documented 1 MiB cap). (TODO check there isn't an undocumented cap on struct size)
|
||||||
- The largest *n*-D byte array is `UNK()` (`LongLength` is `0xUNK` or UNK GiB).
|
- The largest *n*-D byte array is `UNK()` (`LongLength` is `0xUNK` or UNK GiB).
|
||||||
- If a call would allocate beyond those limits (or the process' or machine's limits), an `OutOfMemoryException` will be thrown, which can be caught and handled [but definitely shouldn't be](https://learn.microsoft.com/en-us/dotnet/api/system.outofmemoryexception?view=net-8.0#remarks).
|
- If a call would allocate beyond those limits (or the process' or machine's limits), an `OutOfMemoryException` will be thrown, which can be caught and handled [but definitely shouldn't be](https://learn.microsoft.com/dotnet/api/system.outofmemoryexception?view=net-8.0#remarks).
|
||||||
- All of that is on the managed heap. The default/global stack is OS-specific and [cannot be changed](https://github.com/dotnet/runtime/issues/107183): On Windows, it's 1.5 MiB [due to an oversight](https://github.com/dotnet/runtime/issues/96347#issuecomment-1871528297), and on Linux, it's inherited from the OS, [typically 8 MiB](https://github.com/dotnet/runtime/issues/33622#issuecomment-599462300).
|
- All of that is on the managed heap. The default/global stack is OS-specific and [cannot be changed](https://github.com/dotnet/runtime/issues/107183): On Windows, it's 1.5 MiB [due to an oversight](https://github.com/dotnet/runtime/issues/96347#issuecomment-1871528297), and on Linux, it's inherited from the OS, [typically 8 MiB](https://github.com/dotnet/runtime/issues/33622#issuecomment-599462300).
|
||||||
- The stack size for managed threads can be [specified on init](https://learn.microsoft.com/en-us/dotnet/api/system.threading.thread.-ctor?view=net-8.0#system-threading-thread-ctor(system-threading-threadstart-system-int32)), though as with all of this you may have an XY problem and should reconsider.
|
- The stack size for managed threads can be [specified on init](https://learn.microsoft.com/dotnet/api/system.threading.thread.-ctor?view=net-8.0#system-threading-thread-ctor(system-threading-threadstart-system-int32)), though as with all of this you may have an XY problem and should reconsider.
|
||||||
- If a call would allocate beyond the stack size (or a call chain grows out of control), a `StackOverflowException` will be thrown, which [cannot be caught](https://learn.microsoft.com/en-us/dotnet/api/system.stackoverflowexception?view=net-8.0#remarks).
|
- If a call would allocate beyond the stack size (or a call chain grows out of control), a `StackOverflowException` will be thrown, which [cannot be caught](https://learn.microsoft.com/dotnet/api/system.stackoverflowexception?view=net-8.0#remarks).
|
||||||
|
|
||||||
Under Mono (x64 unless specified and without `gcAllowVeryLargeObjects`, TODO see if Mono respects that):
|
Under Mono (x64 unless specified and without `gcAllowVeryLargeObjects`, TODO see if Mono respects that):
|
||||||
- The largest 1D byte array is `new byte[int.MaxValue]` (just under 2 GiB), as there is no way to instantiate an array with a larger size (`Array.CreateInstance(typeof(T), 0x8000_0000L)` will throw `ArgumentOutOfRangeException: Arrays larger than 2GB are not supported.`, which I suppose is technically incorrect).
|
- The largest 1D byte array is `new byte[int.MaxValue]` (just under 2 GiB), as there is no way to instantiate an array with a larger size (`Array.CreateInstance(typeof(T), 0x8000_0000L)` will throw `ArgumentOutOfRangeException: Arrays larger than 2GB are not supported.`, which I suppose is technically incorrect).
|
||||||
- Similarly, the largest 1D struct array is `new T[int.MaxValue]`. So its size is... unbounded since structs on the heap don't have a size limit.
|
- Similarly, the largest 1D struct array is `new T[int.MaxValue]`. So its size is... unbounded since structs on the heap don't have a size limit.
|
||||||
- The largest *n*-D byte array is `new byte[2, 0x7FFF_FFE6]` (`LongLength` is `0xFFFF_FFCC` or just under 4 GiB). Allocating a single byte more gives an OoME. Multidimensional arrays of other structs appear to also be limited to `0xFFFF_FFCC` octets.
|
- The largest *n*-D byte array is `new byte[2, 0x7FFF_FFE6]` (`LongLength` is `0xFFFF_FFCC` or just under 4 GiB). Allocating a single byte more gives an OoME. Multidimensional arrays of other structs appear to also be limited to `0xFFFF_FFCC` octets.
|
||||||
- If a call would allocate beyond those limits (or the process' or machine's limits), the relevant builtin method will throw an `OutOfMemoryException`, which can be caught and handled [but definitely shouldn't be](https://learn.microsoft.com/en-us/dotnet/api/system.outofmemoryexception?view=netframework-4.8#remarks).
|
- If a call would allocate beyond those limits (or the process' or machine's limits), the relevant builtin method will throw an `OutOfMemoryException`, which can be caught and handled [but definitely shouldn't be](https://learn.microsoft.com/dotnet/api/system.outofmemoryexception?view=netframework-4.8#remarks).
|
||||||
- All of that is on the managed heap. The default/global stack is UNK MiB large and can be changed [externally with `ulimit`](https://github.com/dotnet/runtime/issues/96347#issuecomment-1981511546) (a builtin in most POSIX shells, including BASH), but not with Roslyn.
|
- All of that is on the managed heap. The default/global stack is UNK MiB large and can be changed [externally with `ulimit`](https://github.com/dotnet/runtime/issues/96347#issuecomment-1981511546) (a builtin in most POSIX shells, including BASH), but not with Roslyn.
|
||||||
- The stack size for managed threads can be [specified on init](https://learn.microsoft.com/en-us/dotnet/api/system.threading.thread.-ctor?view=netframework-4.8#system-threading-thread-ctor(system-threading-threadstart-system-int32)), though as with all of this you may have an XY problem and should reconsider. The max. is [1 MiB / 2 MiB (32-bit/64-bit hosts)](https://stackoverflow.com/a/19909421), and there is a [hack to bypass the limit](https://stackoverflow.com/a/48003390) (untested).
|
- The stack size for managed threads can be [specified on init](https://learn.microsoft.com/dotnet/api/system.threading.thread.-ctor?view=netframework-4.8#system-threading-thread-ctor(system-threading-threadstart-system-int32)), though as with all of this you may have an XY problem and should reconsider. The max. is [1 MiB / 2 MiB (32-bit/64-bit hosts)](https://stackoverflow.com/a/19909421), and there is a [hack to bypass the limit](https://stackoverflow.com/a/48003390) (untested).
|
||||||
- If a `stackalloc` call would allocate beyond those limits (with `stackalloc`; TODO check this), or a call chain grows out of control, a `StackOverflowException` will be thrown, which [cannot be caught](https://learn.microsoft.com/en-us/dotnet/api/system.stackoverflowexception?view=netframework-4.8#remarks).
|
- If a `stackalloc` call would allocate beyond those limits (with `stackalloc`; TODO check this), or a call chain grows out of control, a `StackOverflowException` will be thrown, which [cannot be caught](https://learn.microsoft.com/dotnet/api/system.stackoverflowexception?view=netframework-4.8#remarks).
|
||||||
|
|
||||||
Under .NET Framework on Windows (x64 unless specified):
|
Under .NET Framework on Windows (x64 unless specified):
|
||||||
- Untested, but I'm guessing it's probably the same as Mono so long as the [`gcAllowVeryLargeObjects`](https://learn.microsoft.com/en-us/dotnet/framework/configure-apps/file-schema/runtime/gcallowverylargeobjects-element) is enabled in the runtime config, going by those docs and [this blog post](https://www.centerspace.net/large-matrices-and-vectors).
|
- Untested, but I'm guessing it's probably the same as Mono so long as the [`gcAllowVeryLargeObjects`](https://learn.microsoft.com/dotnet/framework/configure-apps/file-schema/runtime/gcallowverylargeobjects-element) is enabled in the runtime config, going by those docs and [this blog post](https://www.centerspace.net/large-matrices-and-vectors).
|
||||||
- Or maybe not; see [this SO answer](https://stackoverflow.com/a/34413257) and the comment below it.
|
- Or maybe not; see [this SO answer](https://stackoverflow.com/a/34413257) and the comment below it.
|
||||||
- The default/global stack is 1 MiB, specified in a PE header. This can be changed [externally with `EDITBIN`](https://stackoverflow.com/a/54584830), but not with Roslyn nor at runtime in any way.
|
- The default/global stack is 1 MiB, specified in a PE header. This can be changed [externally with `EDITBIN`](https://stackoverflow.com/a/54584830), but not with Roslyn nor at runtime in any way.
|
||||||
- The stack size for managed threads [defaults to 1 MiB / 4 MiB (x86/x64)](https://stackoverflow.com/a/5507910) (TODO surely there's an official source) can be [specified on init](https://learn.microsoft.com/en-us/dotnet/api/system.threading.thread.-ctor?view=netframework-4.8#system-threading-thread-ctor(system-threading-threadstart-system-int32)), though as with all of this you may have an XY problem and should reconsider. The max. is UNK MiB (default AppDomain; 1 MiB if untrusted) and the min. [seems to be OS-dependent](https://learn.microsoft.com/en-us/dotnet/api/system.threading.thread.-ctor?view=netframework-4.8#system-threading-thread-ctor(system-threading-threadstart-system-int32)) but was [~256 KiB on Vista](https://techcommunity.microsoft.com/t5/windows-blog-archive/pushing-the-limits-of-windows-processes-and-threads/ba-p/723824) and presumably hasn't been changed since.
|
- The stack size for managed threads [defaults to 1 MiB / 4 MiB (x86/x64)](https://stackoverflow.com/a/5507910) (TODO surely there's an official source) can be [specified on init](https://learn.microsoft.com/dotnet/api/system.threading.thread.-ctor?view=netframework-4.8#system-threading-thread-ctor(system-threading-threadstart-system-int32)), though as with all of this you may have an XY problem and should reconsider. The max. is UNK MiB (default AppDomain; 1 MiB if untrusted) and the min. [seems to be OS-dependent](https://learn.microsoft.com/dotnet/api/system.threading.thread.-ctor?view=netframework-4.8#system-threading-thread-ctor(system-threading-threadstart-system-int32)) but was [~256 KiB on Vista](https://techcommunity.microsoft.com/t5/windows-blog-archive/pushing-the-limits-of-windows-processes-and-threads/ba-p/723824) and presumably hasn't been changed since.
|
||||||
- If a call would allocate beyond the stack size (or a call chain grows out of control), a `StackOverflowException` will be thrown, which [cannot be caught](https://learn.microsoft.com/en-us/dotnet/api/system.stackoverflowexception?view=netframework-4.8#remarks).
|
- If a call would allocate beyond the stack size (or a call chain grows out of control), a `StackOverflowException` will be thrown, which [cannot be caught](https://learn.microsoft.com/dotnet/api/system.stackoverflowexception?view=netframework-4.8#remarks).
|
||||||
- It should be no surprise that all these limits were inherited from native Win32. Thankfully modern .NET is deviating from that where necessary.
|
- It should be no surprise that all these limits were inherited from native Win32. Thankfully modern .NET is deviating from that where necessary.
|
||||||
|
|
||||||
## BCL source
|
## BCL source
|
||||||
|
@ -41,18 +41,18 @@ The API reference on Microsoft Learn (formerly MSDN) now links to the source in
|
||||||
## Const (byte/primitive) arrays
|
## Const (byte/primitive) arrays
|
||||||
|
|
||||||
Not allowed as either array nor `Span`, despite string literals now effectively having the type `const ReadOnlySpan<char>`,
|
Not allowed as either array nor `Span`, despite string literals now effectively having the type `const ReadOnlySpan<char>`,
|
||||||
and despite arrays of primitive types being [allowed for attribute parameters](https://learn.microsoft.com/en-us/dotnet/csharp/advanced-topics/reflection-and-attributes/attribute-tutorial#add-attributes-to-code) since forever.
|
and despite arrays of primitive types being [allowed for attribute parameters](https://learn.microsoft.com/dotnet/csharp/advanced-topics/reflection-and-attributes/attribute-tutorial#add-attributes-to-code) since forever.
|
||||||
Use `static readonly` and weep.
|
Use `static readonly` and weep.
|
||||||
|
|
||||||
## Const structs
|
## Const structs
|
||||||
|
|
||||||
Not allowed, even if they meet the [criteria for unmanaged types](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/unmanaged-types) and are littered with [explicit layout attributes](https://learn.microsoft.com/en-us/dotnet/standard/native-interop/customize-struct-marshalling).
|
Not allowed, even if they meet the [criteria for unmanaged types](https://learn.microsoft.com/dotnet/csharp/language-reference/builtin-types/unmanaged-types) and are littered with [explicit layout attributes](https://learn.microsoft.com/dotnet/standard/native-interop/customize-struct-marshalling).
|
||||||
First-class'd structs are no different, so fields of type `ValueTuple`, `Range`, and as noted above, `Span` cannot be `const`.
|
First-class'd structs are no different, so fields of type `ValueTuple`, `Range`, and as noted above, `Span` cannot be `const`.
|
||||||
Also `ref structs`, which makes slightly more sense. That's probably only because you'd be able to get a reference to a `ref struct` on the heap, something which shouldn't exist, by using reflection.
|
Also `ref structs`, which makes slightly more sense. That's probably only because you'd be able to get a reference to a `ref struct` on the heap, something which shouldn't exist, by using reflection.
|
||||||
|
|
||||||
## Deceptive collection type names
|
## Deceptive collection type names
|
||||||
|
|
||||||
`IReadOnly{Collection,Dictionary,List,Set}` are for getting read-only views of the collections that implement them. They do not mean the collection is immutable (there are [separate classes](https://learn.microsoft.com/en-us/dotnet/api/system.collections.immutable?view=net-6.0) for that). The same goes for `ReadOnlySpan`.
|
`IReadOnly{Collection,Dictionary,List,Set}` are for getting read-only views of the collections that implement them. They do not mean the collection is immutable (there are [separate classes](https://learn.microsoft.com/dotnet/api/system.collections.immutable?view=net-6.0) for that). The same goes for `ReadOnlySpan`.
|
||||||
|
|
||||||
> Kotlin got this right by calling its interfaces e.g. `List`/`MutableList` instead of `IReadOnlyList`/`IList`. (And it also fixed the inheritance hierarchy.)
|
> Kotlin got this right by calling its interfaces e.g. `List`/`MutableList` instead of `IReadOnlyList`/`IList`. (And it also fixed the inheritance hierarchy.)
|
||||||
|
|
||||||
|
@ -117,12 +117,12 @@ public static ReadOnlySpan<TTo> UnsafeDowncast<TFrom, TTo>(ReadOnlySpan<TFrom> s
|
||||||
## MSBuild `Condition` placement
|
## MSBuild `Condition` placement
|
||||||
|
|
||||||
On (older versions of?) VS, `Condition` is ignored if placed on a property/item.
|
On (older versions of?) VS, `Condition` is ignored if placed on a property/item.
|
||||||
It's also limited to a certain subset of expressions when placed on a `<PackageReference/>` (according to [docs](https://learn.microsoft.com/en-us/nuget/consume-packages/package-references-in-project-files#adding-a-packagereference-condition) circa .NET 8).
|
It's also limited to a certain subset of expressions when placed on a `<PackageReference/>` (according to [docs](https://learn.microsoft.com/nuget/consume-packages/package-references-in-project-files#adding-a-packagereference-condition) circa .NET 8).
|
||||||
Create a dedicated `<PropertyGroup/>`/`<ItemGroup/>`.
|
Create a dedicated `<PropertyGroup/>`/`<ItemGroup/>`.
|
||||||
|
|
||||||
## MSBuild project evaluation (without build)
|
## MSBuild project evaluation (without build)
|
||||||
|
|
||||||
[`dotnet publish --getProperty`](https://learn.microsoft.com/en-us/visualstudio/msbuild/evaluate-items-and-properties#use-command-line-options-to-output-values)
|
[`dotnet publish --getProperty`](https://learn.microsoft.com/visualstudio/msbuild/evaluate-items-and-properties#use-command-line-options-to-output-values)
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
```
|
```
|
||||||
|
@ -147,7 +147,7 @@ If a string literal contains a date, *even if it's being deserialised to a strin
|
||||||
|
|
||||||
## NuGet resources are all for old CLI
|
## NuGet resources are all for old CLI
|
||||||
|
|
||||||
[up-to-date docs on MSDN](https://learn.microsoft.com/en-us/nuget/consume-packages/install-use-packages-dotnet-cli)
|
[up-to-date docs on MSDN](https://learn.microsoft.com/nuget/consume-packages/install-use-packages-dotnet-cli)
|
||||||
|
|
||||||
`dotnet list $PWD/BizHawk.sln package --outdated` will list outdated `<PackageReference/>`s (betas are **ignored** without `--include-prerelease`—if there are only betas published, it sees no releases and prints "Not found"). There is no built-in command for updating them automatically.
|
`dotnet list $PWD/BizHawk.sln package --outdated` will list outdated `<PackageReference/>`s (betas are **ignored** without `--include-prerelease`—if there are only betas published, it sees no releases and prints "Not found"). There is no built-in command for updating them automatically.
|
||||||
|
|
||||||
|
@ -168,7 +168,7 @@ See [dotnet/csharplang#53622](https://github.com/dotnet/csharplang/issues/53622)
|
||||||
|
|
||||||
## Preprocessor TFM constants and .NET Standard
|
## Preprocessor TFM constants and .NET Standard
|
||||||
|
|
||||||
The table [here](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/preprocessor-directives#conditional-compilation) is good for reference, but mind the note hidden at the bottom:
|
The table [here](https://learn.microsoft.com/dotnet/csharp/language-reference/preprocessor-directives#conditional-compilation) is good for reference, but mind the note hidden at the bottom:
|
||||||
> The `NETSTANDARD<x>_<y>_OR_GREATER` symbols are only defined for .NET Standard targets, and not for targets that implement .NET Standard [...]
|
> The `NETSTANDARD<x>_<y>_OR_GREATER` symbols are only defined for .NET Standard targets, and not for targets that implement .NET Standard [...]
|
||||||
|
|
||||||
That is, you must use `#if !(NETSTANDARD2_1_OR_GREATER || NETCOREAPP2_1_OR_GREATER)` and not just `#if !NETSTANDARD2_1_OR_GREATER`.
|
That is, you must use `#if !(NETSTANDARD2_1_OR_GREATER || NETCOREAPP2_1_OR_GREATER)` and not just `#if !NETSTANDARD2_1_OR_GREATER`.
|
||||||
|
@ -185,11 +185,11 @@ It seems that `Guid`'s implementation *is* stable across instances, and even acr
|
||||||
|
|
||||||
## `System.Drawing.Color.*` rendered
|
## `System.Drawing.Color.*` rendered
|
||||||
|
|
||||||
[Docs for `Color`](https://learn.microsoft.com/en-us/dotnet/api/system.drawing.color?view=netframework-4.8) don't include any pictures, so [here's a nice chart](https://user-images.githubusercontent.com/13409956/226146254-9a6fc384-c822-41e8-ae6a-3106f9e2986c.svg).
|
[Docs for `Color`](https://learn.microsoft.com/dotnet/api/system.drawing.color?view=netframework-4.8) don't include any pictures, so [here's a nice chart](https://user-images.githubusercontent.com/13409956/226146254-9a6fc384-c822-41e8-ae6a-3106f9e2986c.svg).
|
||||||
|
|
||||||
## `System.Drawing.SystemIcons` rendered
|
## `System.Drawing.SystemIcons` rendered
|
||||||
|
|
||||||
[Docs for `SystemIcons`](https://learn.microsoft.com/en-us/dotnet/api/system.drawing.systemicons?view=netframework-4.8) don't include any pictures, so here they are (Win10, Mono 6.12.x):
|
[Docs for `SystemIcons`](https://learn.microsoft.com/dotnet/api/system.drawing.systemicons?view=netframework-4.8) don't include any pictures, so here they are (Win10, Mono 6.12.x):
|
||||||
|
|
||||||

|

|
||||||

|

|
||||||
|
@ -198,7 +198,7 @@ Notice also the default window icon (`Form.Icon`): on Windows, it's a distinct i
|
||||||
|
|
||||||
## `[ThreadStatic]` field initialisation
|
## `[ThreadStatic]` field initialisation
|
||||||
|
|
||||||
Per [docs](https://learn.microsoft.com/en-us/dotnet/api/system.threadstaticattribute?view=netstandard-2.0#remarks) ([simpler](https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/ca2019#rule-description)), static fields initialisation is moved to the static constructor in IL, which runs on at most 1 thread, so a `[ThreadStatic]` field will be `default` on all other threads if initialised in the usual way.
|
Per [docs](https://learn.microsoft.com/dotnet/api/system.threadstaticattribute?view=netstandard-2.0#remarks) ([simpler](https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2019#rule-description)), static fields initialisation is moved to the static constructor in IL, which runs on at most 1 thread, so a `[ThreadStatic]` field will be `default` on all other threads if initialised in the usual way.
|
||||||
|
|
||||||
Incorrect usage in BizHawk *should* be flagged with CA2019, but apparently it's not working in CI.
|
Incorrect usage in BizHawk *should* be flagged with CA2019, but apparently it's not working in CI.
|
||||||
|
|
||||||
|
@ -210,7 +210,7 @@ If an object being the wrong type is *exceptional*—the method can't handle it
|
||||||
|
|
||||||
## Type constraints (`where` clauses)
|
## Type constraints (`where` clauses)
|
||||||
|
|
||||||
`class` in `where` clauses does not mean "not abstract", it means "reference type". Similarly, `struct` means "value type". There's a lot of complexity re: nullability, so [check the docs](https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/generics/constraints-on-type-parameters) if you're writing a generic method.
|
`class` in `where` clauses does not mean "not abstract", it means "reference type". Similarly, `struct` means "value type". There's a lot of complexity re: nullability, so [check the docs](https://learn.microsoft.com/dotnet/csharp/programming-guide/generics/constraints-on-type-parameters) if you're writing a generic method.
|
||||||
|
|
||||||
TODO euler diagram
|
TODO euler diagram
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue