4

C# 8.0 introduced the Nullable reference types:

https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-8#nullable-reference-types

In short, this new feature allows the specification of a reference variable or property to be null, enabling compiler warnings in case of possible null-reference exception.

Anyway, in case of generic types, the developer is forced to specify whether the generic type must be a struct or a reference type. In other words, this would result in a compiler error:

public class Foo<T>
{
    public T? Bar { get; set; } 
}

[CS8627] A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint.

My question is: is there a way to make generic parameters work both with struct and reference types? Is it mandatory to write two different implementation for struct and reference types?

Panagiotis Kanavos
  • 120,703
  • 13
  • 188
  • 236
Massimiliano
  • 615
  • 4
  • 15
  • What is the context of this code? You can use some workarounds from this [thread](https://stackoverflow.com/questions/54593923/nullable-reference-types-with-generic-return-type/54594285) `[MaybeNull]` can help you – Pavel Anikhouski Jan 09 '20 at 15:12
  • 2
    Short answer: yes, it's mandatory. This is because, on the runtime level, it is not possible to unify `ReferenceType` (whether nullable or not) and `ValueType?` -- the semantics of these are fundamentally different as the latter is *not* a reference. The compiler would have to expend far more effort to make this work than is warranted in this initial implementation (it's not *impossible*, but it's not going to happen any time soon). Note that this is not even restricted to nullable reference types specifically, it's been a bugaboo for longer, but NRTs bring it to the forefront much easier. – Jeroen Mostert Jan 09 '20 at 15:12
  • It's mandatory. That's because a `class?` in reality is just the same old class. The compiler is only going to emit some extra attributes and perform some validations during compilation. A `struct?` in reality is a `Nullable` a completely different type. The compiler has to emit completely different code *and* the extra attributes. This means the compiler needs to know how that generic class is going to be used during compilation – Panagiotis Kanavos Jan 09 '20 at 15:49

0 Answers0