21

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?

3
  • 4
    shameless plug: I wrote a blog post about how it works a little while ago: softwareblog.alcedo.com/post/2010/02/16/… Commented Mar 23, 2010 at 21:44
  • @FredrikMörk The link is no longer available... Commented Feb 6, 2017 at 10:09
  • @M.Mimpen Now it's available again. That blog sort of crashed on me a while ago, but I have republished elsewhere, but have redirects for the original url's. Commented Feb 25, 2017 at 10:11

2 Answers 2

37

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>>)
Sign up to request clarification or add additional context in comments.

4 Comments

How is the boxing handled? Can I implement my own boxing rules for my own structs?
It is handled by special rules in the CLI. No, you cannot do this yourself. Likewise the "lifted" operators aren't something you can do yourself.
It's also worth noting that the behaviour of operators is governed by the language - C# and VB have different rules on this for various operators.
I just ran across a difference: you can give a T? method parameter a default value of T, but if you implement your own kind of nullable and try to do the same, you get a compile error. (E.g., "A value of type 'bool' cannot be used as a default parameter as there are no standard conversions to type 'MyNullable<bool>'".) Does that fall under one of your bullets?
4

Nullable<T> works by providing two fields:

private bool hasValue; internal T value; 

The properties work from those. If you set it to null, hasValue is set to false.

1 Comment

But it is not simply possible because T as well as Nullable<T> are structuress and structure cannot be easily set to null.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.