C# Extension methods

Dzisiaj przybliżę Wam mechanizm metod rozszerzających (extension methods), który jest dostępny w języku C# od wersji 3.0.

Tłumacząc opis znajdujący się na stronie MSDN:

„Metody rozszerzające pozwalają na dodanie metod do istniejących już typów bez potrzeby tworzenia nowego typu pochodnego, ponownej kompilacji kodu lub modyfikowania oryginalnego typu. Są one specjalnym rodzajem metody statycznej ale wywołuje się je tak jakby były metodami rozszerzanego typu. Dla kodu napisanego w C# i VB, nie ma widocznej różnicy pomiędzy wywołaniem metod rozszerzających i metod, które są faktycznie zdefiniowane w typie.”

Myślę, że dobrym przykładem będzie tutaj modyfikacja kodu źródłowego, który znajdziecie w moim wcześniejszym wpisie dotyczącym zapisu i odczytu stanu komponentu DataGridView znajdującego się tutaj .

Przykład zawiera klasę pomocniczą (DataGridViewHelper), która pozwala na zapis i odczyt stanu oraz wywołanie okna konfiguracji widoczności kolumn dla komponentu podanego jako parametr.

Poniżej skrócony wygląd tej klasy.

public static class DataGridViewHelper
{
    public static void ShowConfigurationWindow(DataGridView dataGridView)
    {
        [...]
    }

    public static void LoadConfiguration(DataGridView dataGridView, string fileName)
    {
        [...]
    }

    public static void SaveConfiguration(DataGridView dataGridView, string fileName)
    {
        [...]
    }
}

I dalej tłumaczenie MSDN:

„Metody rozszerzające definiuje się jako statyczne ale są wywoływane przy użyciu składni metody instancji. Ich pierwszy parametr określa typ na jakim będzie ona operowała. Parametr ten jest poprzedzony modyfikatorem this. Aby użyć metod rozszerzających należy dodać za pomocą dyrektywy using, przestrzeń nazw, w której są one zdefiniowane.”

Zatem dostosujmy naszą klasę DataGridViewHelper. Jedyna modyfikacja będzie dotyczyła zmiany nazwy klasy na DataGridViewExtensions oraz nagłówków metod poprzez dodanie modyfikatora this do pierwszego parametru, którym jest referencja do obiektu DataGridView. Sama treść metod pozostanie bez zmian:

public static class DataGridViewExtensions
{
    public static void ShowConfigurationWindow(this DataGridView dataGridView)
    {
        [...]
    }

    public static void LoadConfiguration(this DataGridView dataGridView, string fileName)
    {
        [...]
    }

    public static void SaveConfiguration(this DataGridView dataGridView, string fileName)
    {
        [...]
    }
}

Teraz musimy tylko zmienić kod wywołujący nasze metody. Jest on zawarty w formatce FrmMain przykładu z poprzedniego wpisu:

private void btnConfigure_Click(object sender, EventArgs e)
{
    //DataGridViewHelper.ShowConfigurationWindow(dgvData);
    dgvData.ShowConfigurationWindow();
}

private void btnLoad_Click(object sender, EventArgs e)
{
    using (var dlgOpen = new OpenFileDialog())
    {
        dlgOpen.Filter = "XML files|*.xml";
        if (dlgOpen.ShowDialog() == DialogResult.OK)
        {
            //DataGridViewHelper.LoadConfiguration(dgvData, dlgOpen.FileName);
            dgvData.LoadConfiguration(dlgOpen.FileName);
        }
    }
}

private void btnSave_Click(object sender, EventArgs e)
{
    using (var dlgSave = new SaveFileDialog())
    {
        dlgSave.Filter = "XML files|*.xml";
        if (dlgSave.ShowDialog() == DialogResult.OK)
        {
            //DataGridViewHelper.SaveConfiguration(dgvData, dlgSave.FileName);
            dgvData.SaveConfiguration(dlgSave.FileName);
        }
    }
}

Jak widać, nasze nowe metody są „doklejane” do już istniejącego typu.

Pozostaje jeszcze kwestia umiejscowienia metod rozszerzających. Otóż jedynym wymaganiem jest to, by metoda ta została zdefiniowana w niegenerycznej klasie statycznej. Ja grupuję je według typów, umieszczając je w odpowiednio nazwanych klasach np.:

public static class StringExtensions

lub jak w powyższym przykładzie:

public static class DataGridViewExtensions

Z pomocą przychodzi nam również mechanizm Intellisense dostępny w Visual Studio, który informuje nas o tym, że dana metoda jest metodą rozszerzająca w postaci podpowiedzi oraz stosownej ikonki przy jej nazwie.

Pozdrawiam i życzę miłej pracy!


Tagi:,

komentarze 2 do “C# Extension methods”

  1. Rafal 18 czerwca 2012 w 18:58 #

    Swietny art.

Trackbacks/Pingbacks

  1. C# Extension methods – uzupełnienie | Developer blog - 22 marca 2012

    […] okazji poprzedniego wpisu dotyczącego metod rozszerzających, przypomniałem sobie, że swojego czasu napisałem kod, do sprawdzania poprawności numerów NIP, […]

Dodaj komentarz do Rafal

Uzupełnij * Time limit is exhausted. Please reload the CAPTCHA.