-
Notifications
You must be signed in to change notification settings - Fork 391
C# and .NET docs supplement
To save us repeating our complaints about the lack of proper documentation under each section, let's agree to gather all the frustration here:
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Contribute to the official docs if possible.
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 since forever.
Use static readonly
and weep.
Not allowed, even if they meet the criteria for unmanaged types and are littered with explicit layout attributes.
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.
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 for that). The same goes for ReadOnlySpan
.
Kotlin got this right by calling its interfaces e.g.
List
/MutableList
instead ofIReadOnlyList
/IList
. (And it also fixed the inheritance hierarchy.)
see feature matrix page
You can only have 1 default
branch, but case _ when ...:
doesn't work. However, case var _ when ...:
does.
On (older versions of?) VS, Condition
is ignored if placed on a property/item. Create a new <PropertyGroup/>
.
When <Import/>
ing a .props
file, ProjectDir
is unset (but SolutionDir
is set, if applicable).
Use MSBuildProjectDirectory
. Note that the latter doesn't include a trailing slash.
dotnet list BizHawk.sln package --outdated
will list outdated <PackageReference/>
s
.NET will happily include NUL ((char) 0
) in a string if you use String..ctor(char[])
.
WinForms' Label.Text
stops reading at the first NUL for measurement/rendering, at least under Mono.
The table here 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 [...]
That is, you must use #if !(NETSTANDARD2_1_OR_GREATER || NETCOREAPP2_1_OR_GREATER)
and not just #if !NETSTANDARD2_1_OR_GREATER
.
The GetHashCode
implementation for strings does not reflect the string's contents, and as such, the hash not stable between program instances.
It seems that Guid
's implementation is stable across instances, and even across Mono and .NET 6+ implementations. It also gives 0
for Guid.Empty
which is nice.
Docs for Color
don't include any pictures, so here's a nice chart.
Docs for SystemIcons
don't include any pictures, so here they are (Win10, Mono 6.12.x):
Notice also the default window icon (Form.Icon
): on Windows, it's a distinct icon; on Mono (not shown in the screenshot), it resembles SystemIcon.Application
. From 2.9, EmuHawk overrides the default to the logo.
There are two types of casts in C#: the C-style (T) o
throws if the object is not of the desired type, whereas o as T
evaluates to null
if it's not of the desired type. There's no '?' in this null
-producing operator (this is probably only confusing if you use Kotlin).
If an object being the wrong type is exceptional—the method can't handle it gracefully—then throw a type cast exception straight away. Having it reported as an NRE when there's no null
in sight just frustrates debugging efforts.
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 if you're writing a generic method.
TODO euler diagram
// works
groupBox.ResumeLayout(performLayout: false);
groupBox.PerformLayout();
// breaks subtly
groupBox.ResumeLayout(performLayout: true);