I had a junior developer commenting on a PR that it’s missing a null check before calling an extension method on a string as the string can be null and it would throw a null reference exception. This results in an interesting discussion among the developers.
Let’s say the extension method looks something like this.
public static class StringExtensions
{
public static void Print(this string text)
{
if (text == null)
throw new ArgumentNullException();
Console.WriteLine(text);
}
}
Turns out not many people know the correct answer when I thought it would be fun to ask what exception the following code would throw, a NullReferenceException or ArgumentNullException?
string input = null;
input.Print(); // What exception would be thrown here?
The answer is ArgumentNullException. This is because it is equivalent to calling the extension method like this.
string input = null;
StringExtensions.Print(input);
Even though extension method can be used like an instance method, it is syntactic sugar code for making it cleaner to use and will be literally compiled down to
IL_0001: call void ConsoleApplication.StringExtensions::Print(string)
You are just calling your method like any other method and passing in the parameter. It’s not like instance method where you’re calling a method on the null object at all.
This is actually quite nice and it allows me to write extension methods like the one below to guard against null.
public static class StringExtensions
{
public static string EnsureNotNull(this string text)
{
return text ?? String.Empty;
}
}
I can then call instance methods on a string without having to do a null check. i.e.
public void CalculateSomething(string input)
{
var upperString = input.EnsureNotNull().ToUpper();
// Other logic goes here...
}