Default Literals in C# 7.1

September 09, 2017

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:

[caption id=“attachment_2401” align=“alignnone” width=“300”]Default Literal Default Literal[/caption]

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");
        }
    }
}

[caption id=“attachment_2402” align=“alignnone” width=“300”]Output Output[/caption]

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



Profile picture

A blog about one man's journey through code… and some pictures of the Peak District
Twitter

© Paul Michaels 2022