I came across this issue recently, and realised that I didn’t fully understand extension methods. My previous understanding was that an extension method was simply added to the original class (possible in the same manner that weavers work); However, a construct similar to the following code changed my opinion:
class Program
{
static void Main(string[] args)
{
var myList = GetList();
var newList = myList.Where(
a => a.IsKosher());
var evaluateList = newList.ToList();
foreach(var a in evaluateList)
{
Console.WriteLine(a.Testing);
}
}
static IEnumerable<TestClass> GetList()
{
return new List<TestClass>()
{
new TestClass() {Testing = "123"},
null
};
}
}
public class TestClass
{
public string Testing { get; set; }
}
public static class ExtensionTest
{
public static bool IsKosher(this TestClass testClass)
{
return (!string.IsNullOrWhiteSpace(testClass.Testing));
}
}
As you can see from the code, GetList() returns a null class in the collection. If you run this code, you’ll find that it crashes inside the extension method, because testClass is null.
A note on Linq
If you’re investigating this in the wild, you might find it particularly difficult because of the was that Linq works. Even though the call to the extension method is on the line above, the code doesn’t get run until you actually use the result (in this case, via a ToList()).
New understanding
As I now understand it, extension methods are simply a nice syntactical way to use a static method. That is, had I simply declared my IsKosher method as a standard static method, it would behave exactly the same. To verify this, let’s have a look at the IL; here’s the IL for my function above:
And here’s the IL for the same function as a standard static method:
The only difference is the line at the top of the extension method calling the ExtensionAttribute constructor.