Default Literals in C# 7.1

One of the new features added to the latest* version of C# is that of a “default” literal. What this means is that you can now use the default keyword as though it were a variable. For example, if you were to want to create a new integer and assign it to its default value; you would write something like this:

int i = default(int);

But, surely C# knows you want a default int? In fact, it does, because if you type:

int i = default(long);

Then it won’t compile. Think of how much you could accomplish if you didn’t have to type those extra five characters! That’s where the default literal comes in:

Default Literal

Default Literal

You can also use the literal in comparison statements:

static void Main(string[] args)
{
    int i = default;
 
    Console.WriteLine(i);
 
    for (i = 0; i <= 3; i++)
    {
        if (i == default)
        {
            Console.WriteLine("i is default");
        }
        else
        {
            Console.WriteLine("i NOT default");
        }
    }
}
Output

Output

IL

What’s happening behind the scenes? The following code:

static void Main(string[] args)
{
    int i = default(int);
 
    Console.WriteLine(i);
    Console.ReadLine();
}

Produces the IL:

.method private hidebysig static void  Main(string[] args) cil managed
{
  .entrypoint
  // Code size       17 (0x11)
  .maxstack  1
  .locals init ([0] int32 i)
  IL_0000:  nop
  IL_0001:  ldc.i4.0
  IL_0002:  stloc.0
  IL_0003:  ldloc.0
  IL_0004:  call       void [mscorlib]System.Console::WriteLine(int32)
  IL_0009:  nop
  IL_000a:  call       string [mscorlib]System.Console::ReadLine()
  IL_000f:  pop
  IL_0010:  ret
} // end of method Program::Main

And the code using the new default literal:

static void Main(string[] args)
{
    int i = default;

    Console.WriteLine(i);
    Console.ReadLine();
}

The IL looks vary familiar:

.method private hidebysig static void  Main(string[] args) cil managed
{
  .entrypoint
  // Code size       17 (0x11)
  .maxstack  1
  .locals init ([0] int32 i)
  IL_0000:  nop
  IL_0001:  ldc.i4.0
  IL_0002:  stloc.0
  IL_0003:  ldloc.0
  IL_0004:  call       void [mscorlib]System.Console::WriteLine(int32)
  IL_0009:  nop
  IL_000a:  call       string [mscorlib]System.Console::ReadLine()
  IL_000f:  pop
  IL_0010:  ret
} // end of method Program::Main

Footnotes

* C# 7.1 – Latest at the time of writing

References

https://github.com/dotnet/csharplang/blob/master/proposals/target-typed-default.md

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.