Pojawienie się metod rozszerzających związane jest z potrzebą dodawania nowych funkcji do już istniejących typów danych (szczególnie bibliotekowych i zewnętrznych), nie zmieniając kodu źródłowego tych typów. Jest to szczególnie ważne w nowoczesnych aplikacjach .NET, gdzie potrzebne są dodatkowe udogodnienia, ale nie ma dostępu do modyfikacji klas źródłowych.
Problem polegał na niemożności rozszerzania typów bez tworzenia dziedziczących klas lub opakowań, co prowadziło do skomplikowanej architektury i „fałszywego” dziedziczenia.
Rozwiązanie — metody rozszerzające. W Visual Basic są one zadeklarowane jako moduły z metodami statycznymi oznaczonymi atrybutem <Extension>. Pierwszy parametr metody zawsze wskazuje na rozszerzany typ, co pozwala na wywoływanie metody jak na zwykłym członie obiektu.
Przykład kodu:
Imports System.Runtime.CompilerServices Module StringExtensions <Extension> Public Function ToTitleCase(ByVal str As String) As String If String.IsNullOrEmpty(str) Then Return str Return Char.ToUpper(str(0)) & str.Substring(1).ToLower() End Function End Module ' Użycie: Dim s As String = "visual basic" Console.WriteLine(s.ToTitleCase()) ' Visual basic
Kluczowe cechy:
Czy można wywołać metodę rozszerzającą za pomocą nazwy klasy, a nie instancji?
Tak, metodę rozszerzającą można wywołać również przy pomocy nazwy klasy rozszerzającej jako metody statycznej, po prostu wyraźnie wskazując pierwszy parametr (this/Me).
Przykład kodu:
StringExtensions.ToTitleCase("test string")
Czy można nadpisać (Override) zachowanie metod systemowych przez Extension Methods?
Nie, metody rozszerzające nie nadpisują istniejących metod instancji. W przypadku kolizji nazw wywołana zostanie natywna metoda typu.
Czy metody rozszerzające mogą mieć zmienną liczbę argumentów (ParamArray), na przykład dla ciągów?
Tak, można używać ParamArray w metodach rozszerzających, tak jak w zwykłych metodach statycznych.
W dużym projekcie dla każdego typu tworzone są własne metody rozszerzające z nachodzącymi się nazwami i różną logiką, bez jednego stylu.
Zalety:
Wady:
W module zbierane są tylko uniwersalne i dobrze udokumentowane rozszerzenia do standardowych operacji nad typami. Nazwa każdej metody jasno wskazuje jej przeznaczenie.
Zalety:
Wady: