¿Cómo se implementan los tipos anulables bajo el capó en .net?

En nuestro propio C # de Jon Skeet en profundidad , analiza las 3 formas de simular un ‘nulo’ para los tipos de valores:

  • Valor mágico (por ejemplo, DateTime lo más temprano posible se considera ‘nulo’)
  • Tipo de referencia envoltorio
  • bandera booleana

Se menciona que los tipos que aceptan nulos usan el tercer método. ¿Cómo funcionan exactamente los tipos que aceptan nulos bajo el capó?

En última instancia, son solo una estructura genérica con una bandera bool, excepto con reglas especiales de boxeo. Debido a que las estructuras (por defecto) se inicializan a cero, el valor predeterminado de bool es falso (sin valor):

public struct Nullable where T : struct { private readonly T value; private readonly bool hasValue; public Nullable(T value) { this.value = value; hasValue = true; } public T Value { get { if(!hasValue) throw some exception ;-p return value; } } public T GetValueOrDefault() { return value; } public bool HasValue {get {return hasValue;}} public static explicit operator T(Nullable value) { return value.Value; } public static implicit operator Nullable(T value) { return new Nullable(value); } } 

Diferencias extra, sin embargo:

  • reglas especiales del boxeo (normalmente no puedes hacer esto)
  • Reglas especiales C # para comparar con nulo, etc.
  • operadores “levantados” en C # (y en .NET a través de EqualityComparer , Comparer etc.)
  • reglas especiales sobre restricciones de tipo genérico (para evitar Nullable> )

Nullable funciona proporcionando dos campos:

 private bool hasValue; internal T value; 

Las propiedades funcionan a partir de esos. Si lo configura en null , hasValue se establece en falso.