NNRT = Non-Nullable Reference Type
-
Using attributes
- Feature set similar to what ReSharper delivers today
- Can attributes be added to generic type arguments?
- Compatible with the .NET Framework
- Compatible with languages not supporting NNRTs
- High overhead because every public function must check if the passed function argument might be null
-
Using a struct
- Can be easily optimized by the CLR/JIT
- Compatible with languages not supporting NNRTs
- Incompatible with default(NNRT)
- Special handling of
initobj
- Either:
initobj
of NNRT must not be allowed (easy mode) - Or:
initobj
of NNRT allowed, but must be assigned before used, but also requires checks if NNRTs returned from legacy assembly are initialized (hardcore mode)
- Either:
- Special handling of
ldelem
on NNRT array must check if the loaded element is initialized- The performance should increase as soon as dotnet/coreclr#11407 gets implemented
-
Enhancing the CLR by setting a flag for the Type
- Partially compatible with languages not supporting non-nullable ref types
- Compatible, because the code using NNRTs can be called from languages not supporting them
- Incompatible, because we have two
Type
instances for e.g.System.String
(one nullable, the other non-nullable) Type.IsAssignableFrom
should returntrue
between non-nullable and nullable reference types
- Low overhead, because the JIT can produce optimized machine code for the case where old code - not aware of NNRTs - calls a function that expects a NNRT
- Even lower overhead because all those
if (x == null) throw ...
checks can be removed from the C# code - A
Type
for a NNRT should contain a reference to the same nullable type and back - Assemblies supporting NNRTs must have a special assembly attribute (opt-in)
- In assemblies not supporting NNRTs, comparing types with the equals operator
between NNRT and NRT must return true
- GetHashCode must return the same value for both NNRT and NRT
- Maybe ReferenceEquals should return
true
too for assemblies not supporting NNRTs - Special handling of
initobj
- Either:
initobj
of NNRT must not be allowed (easy mode) - Or:
initobj
of NNRT allowed, but must be assigned before used, but also requires checks if NNRTs returned from legacy assembly are initialized (hardcore mode)
- Either:
ldelem
on NNRT array must check if the loaded element is initialized
- Partially compatible with languages not supporting non-nullable ref types