The value produced by setting all value type fields to their default value and all reference type fields to null.

Nullable type

An instance for which the HasValue property is false and the Value property is undefined.

Default value expressions are particularly useful in generic classes and methods. One issue that arises using generics is how to assign a default value of a parameterized type T when you don't know the following in advance:

Whether T is a reference type or a value type.

If T is a value type, whether it's a numeric value or a struct.

Given a variable t of a parameterized type T, the statement t = null is only valid if T is a reference type. The assignment t = 0 only works for numeric value types but not for structs. To solve that, use a default value expression:

T t = default(T);

The default(T) expression is not limited to generic classes and methods. Default value expressions can be used with any managed type. Any of these expressions are valid:

The following example from the GenericList<T> class shows how to use the default(T) operator in a generic class. For more information, see Introduction to Generics.

namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
// Test with a non-empty list of integers.
GenericList<int> gll = new GenericList<int>();
gll.AddNode(5);
gll.AddNode(4);
gll.AddNode(3);
int intVal = gll.GetLast();
// The following line displays 5.
System.Console.WriteLine(intVal);
// Test with an empty list of integers.
GenericList<int> gll2 = new GenericList<int>();
intVal = gll2.GetLast();
// The following line displays 0.
System.Console.WriteLine(intVal);
// Test with a non-empty list of strings.
GenericList<string> gll3 = new GenericList<string>();
gll3.AddNode("five");
gll3.AddNode("four");
string sVal = gll3.GetLast();
// The following line displays five.
System.Console.WriteLine(sVal);
// Test with an empty list of strings.
GenericList<string> gll4 = new GenericList<string>();
sVal = gll4.GetLast();
// The following line displays a blank line.
System.Console.WriteLine(sVal);
}
}
// T is the type of data stored in a particular instance of GenericList.
public class GenericList<T>
{
private class Node
{
// Each node has a reference to the next node in the list.
public Node Next;
// Each node holds a value of type T.
public T Data;
}
// The list is initially empty.
private Node head = null;
// Add a node at the beginning of the list with t as its data value.
public void AddNode(T t)
{
Node newNode = new Node();
newNode.Next = head;
newNode.Data = t;
head = newNode;
}
// The following method returns the data value stored in the last node in
// the list. If the list is empty, the default value for type T is
// returned.
public T GetLast()
{
// The value of temp is returned as the value of the method.
// The following declaration initializes temp to the appropriate
// default value for type T. The default value is returned if the
// list is empty.
T temp = default(T);
Node current = head;
while (current != null)
{
temp = current.Data;
current = current.Next;
}
return temp;
}
}
}

default literal and type inference

Beginning with C# 7.1, the default literal can be used for default value expressions when the compiler can infer the type of the expression. The default literal produces the same value as the equivalent default(T) where T is the inferred type. This can make code more concise by reducing the redundancy of declaring a type more than once. The default literal can be used in any of the following locations:

variable initializer

variable assignment

declaring the default value for an optional parameter

providing the value for a method call argument

return statement (or expression in an expression bodied member)

The following example shows many usages of the default literal in a default value expression: