Metody rozszerzające
Część sekcji Programowanie obiektowe ścieżki C# w Coddy. Lekcja 39 z 70.
Metody rozszerzające pozwalają dodawać nowe metody do istniejących typów bez modyfikowania ich kodu źródłowego ani tworzenia klas pochodnych. Wyglądają tak, jakby były natywnymi metodami danego typu, dzięki czemu kod jest bardziej czytelny i intuicyjny.
Aby utworzyć metodę rozszerzającą, zdefiniuj metodę statyczną w klasie statycznej, poprzedzając pierwszy parametr słowem kluczowym this:
public static class StringExtensions
{
public static int WordCount(this string str)
{
return str.Split(' ').Length;
}
}Teraz możesz wywołać tę metodę bezpośrednio na dowolnym ciągu znaków:
string sentence = "Hello World Today";
int count = sentence.WordCount(); // 3Parametr this string str informuje kompilator, że ta metoda rozszerza typ string. Gdy wywołujesz sentence.WordCount(), kompilator tłumaczy to w tle na StringExtensions.WordCount(sentence).
Metody rozszerzające mogą również przyjmować dodatkowe parametry:
public static bool IsLongerThan(this string str, int length)
{
return str.Length > length;
}
// Użycie
bool result = "Hello".IsLongerThan(3); // trueTa technika jest szeroko stosowana w LINQ, gdzie metody takie jak Where() i Select() są metodami rozszerzającymi dla IEnumerable. Metody rozszerzające są przydatne do dodawania funkcji pomocniczych do typów, nad którymi nie masz kontroli, dzięki czemu Twój kod pozostaje przejrzysty i wyrazisty.
Wyzwanie
ŁatwyStwórzmy zestaw przydatnych metod rozszerzających dla liczb całkowitych, które dodają wygodne funkcje, jakich można oczekiwać od metod wbudowanych. Utworzysz klasę statyczną zawierającą metody rozszerzające, które można wywoływać bezpośrednio na dowolnej liczbie całkowitej, dzięki czemu Twój kod będzie bardziej wyrazisty i czytelny.
Uporządkujesz kod w dwóch plikach:
IntExtensions.cs: Utwórz klasę statyczną o nazwieIntExtensionsw przestrzeni nazwUtilities. Ta klasa będzie zawierać metody rozszerzające, które rozszerzają typint:IsEven()- zwracatrue, jeśli liczba jest parzysta, w przeciwnym raziefalseSquare()- zwraca liczbę pomnożoną przez samą siebieIsInRange(int min, int max)- zwracatrue, jeśli liczba mieści się w zakresie od min do max (włącznie), w przeciwnym raziefalse
this, aby określić, jaki typ rozszerzasz.Program.cs: W pliku głównym wczytaj liczbę całkowitą z wejścia i zaprezentuj wszystkie trzy metody rozszerzające. Wywołaj każdą metodę bezpośrednio na liczbie całkowitej, tak jakby była metodą wbudowaną, a następnie wypisz wyniki.
Otrzymasz trzy dane wejściowe:
- Liczba do sprawdzenia (liczba całkowita)
- Minimalna wartość do sprawdzenia zakresu (liczba całkowita)
- Maksymalna wartość do sprawdzenia zakresu (liczba całkowita)
Wypisz wynik w tym formacie:
Is {number} even? {True/False}
Square of {number}: {result}
Is {number} in range [{min}-{max}]? {True/False}Na przykład, jeśli danymi wejściowymi są 7, 5 i 10, wynik powinien wyglądać następująco:
Is 7 even? False
Square of 7: 49
Is 7 in range [5-10]? TrueZwróć uwagę, jak naturalnie można napisać number.IsEven() i number.Square() — metody rozszerzające sprawiają wrażenie, jakby od zawsze były częścią typu liczby całkowitej!
Spróbuj swoich sił
using System;
using Utilities;
class Program
{
public static void Main(string[] args)
{
// Wczytaj dane wejściowe
int number = Convert.ToInt32(Console.ReadLine());
int min = Convert.ToInt32(Console.ReadLine());
int max = Convert.ToInt32(Console.ReadLine());
// TODO: Użyj metod rozszerzających dla 'number' i wypisz wyniki
// Wywołaj number.IsEven(), number.Square() i number.IsInRange(min, max)
// Wypisz w formacie:
// Czy {number} jest parzyste? {True/False}
// Kwadrat liczby {number}: {result}
// Czy {number} mieści się w przedziale [{min}-{max}]? {True/False}
}
}
Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.
Wszystkie lekcje w sekcji Programowanie obiektowe
1Podstawy programowania obiektowego
Pliki zewnętrznePrzestrzenie nazw i dyrektywyWprowadzenie do klas i obiektówSłowo kluczowe „this”Metody i parametryPola a właściwościKonstruktoryInicjalizatory obiektówPodsumowanie — prosty kalkulator4Dziedziczenie
Podstawowa składnia dziedziczenia (:)Słowo kluczowe 'base'Słowa kluczowe virtual i overrideKlasy sealedBazowa klasa 'object'Powtórzenie – hierarchia pracowników7Zaawansowane funkcje
Przeciążanie operatorówIndeksery (this[])Nadpisywanie ToString()Metody rozszerzającePodsumowanie – własna lista2Właściwości i składowe statyczne
Właściwości automatyczneWłaściwości tylko do odczytu i zapisuPola i metody statyczneKlasy statyczneSkładowe z ciałem wyrażeniowym5Polimorfizm i interfejsy
Polimorfizm czasu kompilacji a czasu wykonaniaInterfejs a klasa abstrakcyjnaWiele interfejsówJawne implementowanie interfejsówRzutowanie w górę i w dółPowtórka — kalkulator kształtów8Zaawansowane koncepcje OOP
Kompozycja zamiast dziedziczeniaTypy generyczne (klasy i metody)Delegaty i zdarzeniaAtrybuty i refleksjaIDisposable i instrukcja usingPodstawy wstrzykiwania zależności11Wzorce projektowe, część 2
Wzorzec poleceniaWzorzec adapteraWzorzec dekoratoraWzorzec metody szablonowejWzorzec stanuWzorzec kompozytu3Architektura klas
Dane instancji a dane statyczneSłowa kluczowe 'readonly' i 'const'Pola zapasowePowtórzenie — menedżer kont bankowych6Hermetyzacja
Modyfikatory dostępuWłaściwości w hermetyzacjiImplementacja ukrywania danychWzorce niezmiennościPowtórka — dane studentów9Argumenty zmiennej liczby
Słowo kluczowe „params”Parametry opcjonalneArgumenty nazwanePrzeciążanie metodPoćwicz samodzielnie: Kompilator C# online