Při studiu programování v C# je jedná z prvních pouček, se kterou se člověk setká, ta, která říká, že když chceme pracovat s referenčním typem, měli bychom si být jisti, že jeho hodnota není null, protože jinak bychom se mohli dočkat nepěkné NullReferenceException. Co byste řekli, že udělá následující kód v C# 3.0?
List<string> list = null;
list.ToMyString();
Na první pohled se zdá, že se kód ani nepřeloží, protože standardní třída List<T> přeci nedisponuje žádnou metodou ToMyString(). Ale kód nejen, že se přeloží, ale dokonce ani nezhavaruje na zmíněné NullReferenceException! To všechno díky novému konstruktu jazyka C# 3.0 – extension metodě. Metoda ToMyString() je totiž definována takto:
public static class MyExtensions
{
public static string ToMyString(this object o)
{
return o == null ? "null" : o.ToString();
}
}
Extension metoda není nic jiného než statická metoda umístěná ve statické třídě mající před prvním parametrem klíčové slovo this. Právě typ tohoto prvního parametru udává, pro jaký typ zavádíme novou metodu. Metodu pak můžeme na daném typu použít tehdy, pokud se nacházíme ve stejném jmenném prostoru jako statická třída nebo máme tento namespace nausingován.
Z hlediska vygenerovaného CIL je jediný rozdíl mezi normální statickou metodou a extension metodou jen v tom, že extension metoda a obalující statická třída jsou odekorovány atributem System.Runtime.CompilerServices. ExtensionAttribute. Volání obou metod probíhá zcela identicky.
Tím se dostáváme k odpovědi na otázku, proč lze volat extension metody i na nullové reference. Inu je tomu tak, protože první ukázka generuje úplně stejný CIL jako následující kód:
List<string> list = null;
MyExtensions.ToMyString(list);
Díky extension metodám se tedy můžeme setkat s obdobným kódem jako v první ukázce, který nezhavaruje na NullReferenceException tam, kde bychom to na první pohled očekávali – interesting…