0Pricing
C# Academy · Lekcja

Definiowanie metod rozszerzających

Pisz metody statyczne z modyfikatorem this.

Definiowanie metod rozszerzających to bezpłatna lekcja C# Academy na CoddyKit. To lekcja 1 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej C# Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs C# Academy zawiera 4 lekcji w sumie.

Czym jest metoda rozszerzająca?

Metoda rozszerzająca pozwala dodać nowe metody do istniejącego typu bez jego modyfikowania i bez tworzenia typu pochodnego. Wywołuje się ją tak, jakby była metodą instancji, ale w rzeczywistości jest specjalną metodą static.

Metody rozszerzające są idealne, gdy nie mają Państwo dostępu do kodu źródłowego danego typu (takiego jak string lub int), ale chcą Państwo dodać do niego wygodne nowe zachowanie.

Trzy wymagania

Do zadeklarowania metody rozszerzającej potrzebne są: klasa statyczna, metoda statyczna oraz pierwszy parametr oznaczony słowem kluczowym this. Parametr this wskazuje typ, który jest rozszerzany.

using System;

public static class StringExtensions
{
    public static int WordCount(this string text)
    {
        if (string.IsNullOrWhiteSpace(text)) return 0;
        return text.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).Length;
    }
}

public class Program
{
    public static void Main()
    {
        string sentence = "the quick brown fox";
        Console.WriteLine(sentence.WordCount());
    }
}

Wywoływanie jak metody instancji

Mimo że WordCount jest statyczna, wywołuje się ją jako sentence.WordCount(). Kompilator przekształca za kulisami to wywołanie na StringExtensions.WordCount(sentence).

using System;
using System.Linq;

public static class StringExtensions
{
    public static string Repeat(this string text, int times)
    {
        return string.Concat(Enumerable.Repeat(text, times));
    }
}

public class Program
{
    public static void Main()
    {
        // These two lines do exactly the same thing
        Console.WriteLine("ab".Repeat(3));
        Console.WriteLine(StringExtensions.Repeat("ab", 3));
    }
}

Parametr this otrzymuje instancję

Wartość znajdująca się po lewej stronie kropki staje się parametrem this. Można dodać za nim kolejne parametry, które wywołujący przekazuje w zwykły sposób.

using System;

public static class IntExtensions
{
    public static bool IsBetween(this int value, int low, int high)
    {
        return value >= low && value <= high;
    }
}

public class Program
{
    public static void Main()
    {
        int age = 25;
        Console.WriteLine(age.IsBetween(18, 65));
        Console.WriteLine(10.IsBetween(1, 5));
    }
}

Rozszerzanie własnych typów

Metody rozszerzające nie służą wyłącznie do rozszerzania typów bibliotecznych. Można rozszerzać za ich pomocą również własne klasy, co ułatwia zachowanie przejrzystego typu podstawowego i dodawanie metod pomocniczych w innych miejscach.

using System;

public class Money
{
    public decimal Amount { get; }
    public Money(decimal amount) { Amount = amount; }
}

public static class MoneyExtensions
{
    public static string ToUsd(this Money m) => "$" + m.Amount.ToString("0.00");
}

public class Program
{
    public static void Main()
    {
        var price = new Money(19.5m);
        Console.WriteLine(price.ToUsd());
    }
}

Metody rozszerzające nie mają dostępu do prywatnych składowych

Metoda rozszerzająca jest jedynie metodą statyczną w innej klasie, dlatego może korzystać wyłącznie z publicznego interfejsu typu (lub z elementów internal, gdy znajduje się w tym samym zestawie). Nie może uzyskać dostępu do prywatnych pól.

using System;

public class Counter
{
    private int _count;
    public int Value => _count;
    public void Increment() => _count++;
}

public static class CounterExtensions
{
    // Can only use public members like Value and Increment
    public static bool IsZero(this Counter c) => c.Value == 0;
}

public class Program
{
    public static void Main()
    {
        var c = new Counter();
        Console.WriteLine(c.IsZero());
        c.Increment();
        Console.WriteLine(c.IsZero());
    }
}

Łączenie metod rozszerzających

Ponieważ każda metoda rozszerzająca zwraca wartość, można łączyć je w płynny potok operacji. Taki zapis czyta się od góry do dołu i jest stosowany przez LINQ.

using System;

public static class TextExtensions
{
    public static string Shout(this string s) => s.ToUpper();
    public static string Bang(this string s) => s + "!";
}

public class Program
{
    public static void Main()
    {
        string result = "hello".Shout().Bang();
        Console.WriteLine(result);
    }
}

Wartość null i metody rozszerzające

W przeciwieństwie do rzeczywistego wywołania metody instancji metoda rozszerzająca może wykonać się nawet wtedy, gdy odbiorca ma wartość null, ponieważ do wyłuskania wartości nie dochodzi, dopóki kod nie spróbuje jej użyć. Pozwala to pisać pomocnicze metody bezpiecznie obsługujące null.

using System;

public static class StringExtensions
{
    public static bool IsBlank(this string text)
    {
        // text may be null here, and that is fine
        return string.IsNullOrWhiteSpace(text);
    }
}

public class Program
{
    public static void Main()
    {
        string nothing = null;
        Console.WriteLine(nothing.IsBlank());
        Console.WriteLine("x".IsBlank());
    }
}

Metody instancji mają pierwszeństwo przed rozszerzeniami

Jeśli istnieje rzeczywista metoda instancji o pasującej sygnaturze, kompilator zawsze wybiera ją zamiast metody rozszerzającej. Metody rozszerzające jedynie uzupełniają funkcje, których dany typ jeszcze nie zapewnia.

using System;

public static class Ext
{
    // This will be ignored because string already has ToString()
    public static string ToString(this string s, int n) => s + n;
}

public class Program
{
    public static void Main()
    {
        // Resolves to the built-in instance ToString(), not the extension
        Console.WriteLine("value: " + "abc".ToString());
    }
}

Praktyczna biblioteka metod pomocniczych

Grupowanie powiązanych metod rozszerzających w jednej klasie statycznej pozwala utworzyć uporządkowaną bibliotekę narzędziową. Oto niewielka klasa pomocnicza do operacji na liczbach, którą można ponownie wykorzystać w całym projekcie.

using System;

public static class NumberExtensions
{
    public static bool IsEven(this int n) => n % 2 == 0;
    public static int Squared(this int n) => n * n;
    public static double Percent(this int n) => n / 100.0;
}

public class Program
{
    public static void Main()
    {
        Console.WriteLine(4.IsEven());
        Console.WriteLine(5.Squared());
        Console.WriteLine(50.Percent());
    }
}

Proszę spróbować samodzielnie

Proszę połączyć zdobytą wiedzę: utworzyć jedną klasę statyczną z kilkoma wyspecjalizowanymi metodami rozszerzającymi i wywoływać je w płynny sposób. Dokładnie tak buduje się codzienne biblioteki metod pomocniczych.

using System;

public static class StringExtensions
{
    public static string Capitalize(this string s)
        => string.IsNullOrEmpty(s) ? s : char.ToUpper(s[0]) + s.Substring(1);
    public static string Surround(this string s, char c) => c + s + c;
}

public class Program
{
    public static void Main()
    {
        Console.WriteLine("hello".Capitalize().Surround('*'));
    }
}

Szybkie sprawdzenie

Sprawdź swoją wiedzę na temat deklarowania metod rozszerzających.

Powtórzenie

Dowiedzieli się Państwo, że metoda rozszerzająca jest metodą static w klasie static, której pierwszy parametr używa this. Wywołuje się ją za pomocą składni instancji, ale kompiluje się ona do zwykłego wywołania statycznego.

  • Trzy wymagania: klasa statyczna, metoda statyczna i pierwszy parametr this.
  • Dostępne są wyłącznie składowe publiczne.
  • Metody instancji zawsze mają pierwszeństwo.
  • Metody rozszerzające można łączyć, a nawet wykonywać dla odbiorców o wartości null.

Często zadawane pytania

Czy lekcja „Definiowanie metod rozszerzających” jest bezpłatna?

Tak — pełny tekst „Definiowanie metod rozszerzających” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu C# Academy, przejdź na CoddyKit PRO. Kurs C# Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „Definiowanie metod rozszerzających”?

Pisz metody statyczne z modyfikatorem this. Ćwiczysz C# Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć C# Academy?

Nie wymagamy żadnego doświadczenia. C# Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 1 z 4.

Ile czasu zajmuje lekcja „Definiowanie metod rozszerzających”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji C# Academy?

Tak. Każda lekcja C# Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Definiowanie metod rozszerzających
  2. Rozszerzanie interfejsów i typów generycznych
  3. Rozstrzyganie metod rozszerzających
  4. Projektowanie dobrych rozszerzeń
← Powrót do C# Academy