Introduction
Default
represents default value of T
parameter in generics instructions. In several cases, the default
keyword is an absolute unknown and we think it’s unnecessary or its functionality is null
. There are some development moments with the generics classes where default
keyword can be useful.
Default
keyword can make our work easier and it may make the code safer.
Default(T)
This keyword returns the default value of type parameter
.
These are the default values for the more important types inside of CLR:
Classes
-> null
.
Nullable<T>
-> null
.
Numerics structs (int, double, decimal, etc)
-> 0
.
DateTime structs
-> 01/01/0001
.
Char structs
-> empty char
.
Bool structs
-> false
.
Evaluation Initializes T Parameters
This is a very simple generic method example. This method has two ref
parameters of T
type and changes your values in the implementation.
public static void ChangeValues<T>(ref T a, ref T b)
{
T _a = a;
T _b = b;
a = _b;
b = _a;
}
The ChangeValues
method hasn’t generic restriction filter so that T
will be any type (reference type or value type)
If necessary, validate if the parameters have been initialized (has a valid value different to initialize value), add a validation chunk:
public static void ChangeValues<T>(ref T a, ref T b)
{
if(a.Equals(null) || b.Equals(null))
{
throw new ArgumentException("....");
}
T _a = a;
T _b = b;
a = _b;
b = _a;
}
We have a problem, because this implementation doesn’t verify the default value types.
It will be a wrong execution:
static void Main(string[] args)
{
DateTime a = new DateTime();
DateTime b = DateTime.Today;
System.Console.WriteLine($"a --> {a}");
System.Console.WriteLine($"b --> {b}");
System.Console.WriteLine();
ChangeValues(ref a, ref b);
System.Console.WriteLine($"a --> {a}");
System.Console.WriteLine($"b --> {b}");
System.Console.Read();
}
Console output:
To correct this bug, we will a new method version with the default keyword inclusion:
public static void NewChangeValues<T>(ref T a, ref T b)
{
if (a.Equals(default(T)) || b.Equals(default(T)))
{
throw new ArgumentException("....");
}
T _a = a;
T _b = b;
a = _b;
b = _a;
}
Create Empty Instance
Another example could be the possibility to create empty instance of T
types without reflection (Activator
).
public T CreateEmptyInstace<T>(T item)
{
var result = default(T);
return result;
}
Reset Generics Instances
Another use case for Default(T)
could be for reset instance of generics objects.
public void ResetValue<T>(ref T item)
{
item = default(T);
}