Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how are nullable types implemented under the hood in .net?

Tags:

In our own Jon Skeet's C# in depth, he discusses the 3 ways to simulate a 'null' for value types:

  • Magic value (e.g. earliest possible DateTime is taken to be 'null')
  • Reference type wrapper
  • boolean flag

It is mentioned that nullable types use the third method. How exactly do nullable types work under the hood?

like image 748
Gordon Gustafson Avatar asked Mar 23 '10 21:03

Gordon Gustafson


People also ask

How are nullable types declared in C#?

You can declare nullable types using Nullable<t> where T is a type. Nullable<int> i = null; A nullable type can represent the correct range of values for its underlying value type, plus an additional null value. For example, Nullable<int> can be assigned any value from -2147483648 to 2147483647, or a null value.

Are nullable types reference types in C#?

No, a nullable is a struct.

How do you make an int nullable in C#?

C# 2.0 introduced nullable types that allow you to assign null to value type variables. You can declare nullable types using Nullable where T is a type. Nullable types can only be used with value types. The Value property will throw an InvalidOperationException if value is null; otherwise it will return the value.

Does HasValue check for null?

There are two public read-only properties, HasValue and Value , in an instance of a nullable type. While the former is used to check if the nullable variable contains a value, the latter is used to retrieve the value contained inside the nullable variable. Note that HasValue has a default value of false.


1 Answers

Ultimately, they are just a generic struct with a bool flag - except with special boxing rules. Because structs are (by default) initialized to zero, the bool defaults to false (no value):

public struct Nullable<T> 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<T> value) {         return value.Value; }     public static implicit operator Nullable<T>(T value) {         return new Nullable<T>(value); } } 

Extra differences, though:

  • special boxing rules (you can't normally do this)
  • special C# rules for comparing to null etc
  • "lifted" operators in C# (and in .NET via EqualityComparer<T>, Comparer<T> etc)
  • special rules on generic type constraints (to prevent Nullable<Nullable<T>>)
like image 195
Marc Gravell Avatar answered Sep 20 '22 14:09

Marc Gravell