Menu

Delegate – czyli delegaty od podstaw cz.1

19 lipca 2017 - .NET, Podstawy

Delegaty ogólnie:

A więc co to jest delegat (ang. delegate). Jest to obiekt typu referencyjnego, który wskazuje na metodę lub metody o określonej sygnaturze. Delegaty są mniej więcej podobne do wskaźników funkcji w języku C ++, jednak posiadają większe możliwości. Typowa sytuacja użycia delegatów ma miejsce, kiedy kod, który ma wykonać pewne operacje, nie zna ich dokładnej treści.
Dla przykładu klasa Thread może wykonać zadanie w nowym wątku po starcie, ponieważ przekazałeś jej w konstruktorze instancję delegata typu ThreadStart lub ParameterizedThredStart.

Aby delegaty mogły cokolwiek zrobić:

 

Deklaracja typu delegatowego:

[modifiers] delegate result-type identifier ([formal-parameters]);

np.

public delegate void StrigProcessor(string input)

Gdzie:

Powyższa deklaracja mówi, że jeżeli chcemy stworzyć instancję delegata StringProcessor, będziemy potrzebować metody, która posiada typ zwracany void, oraz przyjmuje jeden parametr typu string.

 

Wyszukiwanie odpowiedniej metody dla instancji delegata:

Kolejnym krokiem jest znalezienie lub napisanie metody która spełnia wszystkie wymagane warunki, czyli zgadzają się parametry oraz typ zwracany – tak jak ma to miejsce w przypadku wywołania zwykłej metody. Dla przykładu dla powyższego typu delegatowego będzie pasowała tylko jedna z poniższych metod:

void PrintString(string s)
void PrintInteger(int i)
void PrintTwoStrings(string x, string y)
int GetStringLength(string s)
void PrintObject(object x)

Jedyną pasującą metodą jest metoda pierwsza – ponieważ tylko w tym przypadku zgadza się zarówno typ zwracany jak i parametry. Co prawda od wersji C# 4.0 istnieją jeszcze inne możliwości, jednak tym zajmiemy się w innym czasie.

 

Tworzenie instancji delegata:

A więc mamy juz typ delegatowy oraz odpowiadającą mu metodę z własciwą sygnaturą. Możemy teraz przystąpić do stworzenia instancji delegata, tak żeby wybrana przez nas metoda została wykonana.

 StringProcessor proc1 = new StringProcessor(PrintString) 

 

Wywołanie instancji delegata:

Wywołanie delegata jest bardzo proste. Wywołuje się do tak jak zwykłą funkcję.

 proc1("Some string"); 

Przykładowy kod:

using System;

namespace SimpleDelegateBlog
{
    class Program
    {
        public delegate void StringProcessor(string input);
        static void Main(string[] args)
        {
            StringProcessor proc1 = new StringProcessor(PrintString);
            proc1("Some string");
        }

        static void PrintString(string s)
        {
            Console.WriteLine(s);
        }
    }
}

Na wyjściu w konsoli zostanie wyświetlony napis: Some string

 

Delegaty złożone:

Do tej pory omówiliśmy delegaty posiadające jedną akcję. Bardzo ważną i przydatną funkcją jest możliwość tworzenia grup delegatów. Utworzoną grupę nazywamy delegatem złożonym. Łączyć ze sobą można jedynie delegaty tego samego typu. Do dodawania delagata do grupy możemy posłużyć się operatorem „+” lub „+=”. Podobnie dla usuwania delegatów z delegata złożonego posłużymy się operatorami „-” lub „-=”. Łączenie i usuwanie delegatów jest szczególnie przydatne w zdarzeniach, gdzie możemy chcieć wykonać wiele akcji.

Poniżej prosty kod obrazujący jak wygląda łączenie delegatów:

using System;

namespace SimpleDelegateBlog
{
    class Program
    {
        public delegate void StringProcessor(string input);

        static void Main(string[] args)
        {
            // Stworzenie delegata złozonego
            StringProcessor proc;

            // Stowrzenie instancji naszych poszczególnych delegatów
            StringProcessor proc1 = new StringProcessor(PrintString);
            StringProcessor proc2 = new StringProcessor(PrintString2);

            // Stworzenie instancji delegata złozonego
            proc = proc1;
            proc += proc2;

            // Wywołanie delegata złozonego
            proc("Some string");
        }

        static void PrintString(string s)
        {
            Console.WriteLine(s + " written by PrintString method");
        }        
        static void PrintString2(string s)
        {
            Console.WriteLine(s + " written by PrintString2 method");
        }
    }
}

Na wyjściu w konsoli dostaniemy:
Some string written by PrintString method
Some string written by PrintString2 method

 

Więcej o delegatach w połączeniu z wyrażeniami lambda możecie się dowiedzieć w kolejnym moim poście – „Wyrażenia lambda – delegaty cz.2”

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *