I was always doing check for null (VB.NET: Nothing)
This not quite correct. Nothing is not the same as null; Nothing means null when assigned or compared to a nullable type (reference type or Nullable<T>) with = or when compared using Is Nothing and means the default value for a non-nullable value type it is assigned to or compared with =.
Hence the VB:
Dim b as Boolean = 0 = Nothing ' b is True
is not the same as the C#:
bool b = 0 == null; // b is false
but rather of:
bool b = 0 == default(int); // b is true
So the VB.NET equivalent of default(T) is indeed Nothing when not compared using Is.
In VB.NET you are not allowed to do val Is Nothing with val is not nullable, while in C# you can do val == null but it causes a warning (and always results in false).
In VB.NET you are allowed to do val Is Nothing with a generic type that could be nullable, and likewise with C# and val == null, in which case the check is that val is a nullable type and that it is set to null (and a waste-free one at that, generally in the case of a non-nullable type the jitter optimises away anything that would happen if val == null/val Is Nothing since it knows that can never happen).
The following VB.NET and C# methods are equivalent:
public static bool Demonstrate<T>(T x)
{
T y = default(T);
bool isNull = x == null;
bool isDefault = x.Equals(default(T));
int zero = default(int)
return zero == default(int);
}
Public Shared Function Demonstrate(Of T)(x As T) As Boolean
Dim y As T = Nothing
Dim isNull As Boolean = x Is Nothing
Dim isDefault As Boolean = x.Equals(Nothing)
Dim zero As Integer = Nothing
Return zero = Nothing
End Function