Uvod: Šta su to delegati?

Delegati u C# su specijalan tip koji omogućava da se funkcije (metode) tretiraju kao objekti. Na ovaj način možemo prosleđivati funkcije kao parametre drugim funkcijama, ili im dodeljivati različite funkcije dinamički tokom izvršavanja programa.

Delegat je, u suštini, kao pokazivač na funkciju — on "drži" referencu na neku funkciju koju kasnije možemo pozvati.

Poređenje sa zadavanjem zadataka: Delegat je kao osoba kojoj možete zadati određeni zadatak (ili funkciju). Zamislite da imate prijatelja kojem možete reći šta treba da uradi. Na primer, možete ga zamoliti da pošalje poruku ili da kupi doručak. Delegat u C# radi nešto slično: on je „posrednik“ koji zna koji zadatak treba da izvrši (metod) i možete ga koristiti za pokretanje tog zadatka u kodu.
ili...
Delegat je kao daljinski upravljač: Zamislite delegat kao daljinski upravljač za TV. Daljinski upravljač ne zna koji TV kontroliše, ali zna kako da promeni kanal ili pojača ton. Kada ga povežete sa TV-om, delegat može pokrenuti određene funkcije (kao što su pojačavanje tona ili promenu kanala) na tom TV-u. U C#-u, delegat je objekat koji može pozvati neku funkciju, ali ne zna koju dok ne povežete konkretan metod.

Delegat može pokrenuti različite funkcije u zavisnosti od toga koja je funkcija u njega postavljena.

Osnovna sintaksa delegata

Definicija delegata u C#:

public delegate void MojDelegat(string poruka);

Ovaj delegat definiše tip metoda koji može primiti jedan string argument i ne vraća nikakav rezultat (tip void).

Korišćenje delegata

Evo kako možemo koristiti delegat u programu:

public delegate void MojDelegat(string poruka);

class Program
{
    static void Main()
    {
        // Kreiramo instancu delegata i povežemo je sa metodom Pozdravi
        MojDelegat delegat = Pozdravi;

        // Pozivamo metod kroz delegat
        delegat("Zdravo, svete!");
    }

    // Metod koji odgovara potpisu delegata
    public static void Pozdravi(string poruka)
    {
        Console.WriteLine(poruka);
    }
}

Objašnjenje:
  1. Definisali smo delegat MojDelegat, koji prima jedan string parametar i ne vraća ništa.
  2. Kreirali smo instancu delegata i povezali je sa metodom Pozdravi, koji takođe prima jedan string parametar i ne vraća ništa.
  3. Poziv delegata je zapravo poziv metode Pozdravi putem delegata.

Pojednostavljeno objašnjenje:

  • Delegat je kao kutija: U tu "kutiju" stavljamo funkciju. Kada pozovemo delegat, zapravo otvaramo tu kutiju i pokrećemo funkciju koju smo prethodno stavili unutra.

  • Zašto koristiti delegat?: Možemo promeniti šta je u "kutiji" bez potrebe da menjamo ostatak koda. Tako možemo izabrati koju funkciju ćemo pokrenuti u različitim situacijama. Na primer, možemo staviti različite funkcije u delegat i pozvati ih u zavisnosti od situacije.

Delegati su veoma korisni kada želimo da koristimo isti delegat za pozivanje različitih metoda. Time postižemo veću fleksibilnost u kodu jer jedan delegat može referencirati različite funkcije koje obavljaju različite poslove, ali imaju isti potpis (iste parametre i povratni tip).

Primer 2:

Zamislimo da želimo da kreiramo delegat koji može pozvati različite metode za različite vrste obrade teksta: da prikaže tekst u originalnom obliku, da ga prikaže velikim slovima ili malim slovima.

using System;

// Definišemo delegata koji prima string i ne vraća ništa (void)
public delegate void ObradaTekstaDelegat(string tekst);

class Program
{
    static void Main()
    {
        // Kreiramo delegat i dodeljujemo mu metod koji prikazuje tekst u originalnom obliku
        ObradaTekstaDelegat obrada = PrikaziOriginalno;

        // Pozivanje delegata - prikazuje tekst u originalnom obliku
        obrada("Delegati su korisni!"); // Ispisuje: Delegati su korisni!

        // Menjamo delegat da pokazuje na metod koji prikazuje tekst velikim slovima
        obrada = PrikaziVelikaSlova;
        obrada("Delegati su korisni!"); // Ispisuje: DELEGATI SU KORISNI!

        // Menjamo delegat da pokazuje na metod koji prikazuje tekst malim slovima
        obrada = PrikaziMalaSlova;
        obrada("Delegati su korisni!"); // Ispisuje: delegati su korisni!
    }

    // Metod koji prikazuje tekst u originalnom obliku
    public static void PrikaziOriginalno(string tekst)
    {
        Console.WriteLine(tekst);
    }

    // Metod koji prikazuje tekst velikim slovima
    public static void PrikaziVelikaSlova(string tekst)
    {
        Console.WriteLine(tekst.ToUpper());
    }

    // Metod koji prikazuje tekst malim slovima
    public static void PrikaziMalaSlova(string tekst)
    {
        Console.WriteLine(tekst.ToLower());
    }
}        
        

Objašnjenje:
  1. Delegat ObradaTekstaDelegat je definisan tako da prima string i ne vraća ništa (void).
  2. Delegat može referencirati bilo koju funkciju koja prima string kao parametar i ne vraća vrednost.
  3. U glavnom programu, kreiramo instancu delegata i prvo ga povežemo sa metodom PrikaziOriginalno koji ispisuje tekst onako kako je prosleđen.
  4. Nakon toga, menjamo delegat tako da pokazuje na metod PrikaziVelikaSlova, koji ispisuje tekst velikim slovima.
  5. Zatim delegat povezujemo sa metodom PrikaziMalaSlova, koji ispisuje tekst malim slovima.

U ovom primeru, isti delegat koristi se za pozivanje različitih metoda u zavisnosti od situacije, a svi ti metodi imaju isti potpis.



A sada da proširimo priču: Šta su to GENERIČKI DELEGATI?

Generički delegati omogućavaju definisanje delegata koji mogu raditi sa različitim tipovima podataka.

Ključni pojmovi koje bi trebalo znati:

  • Delegat: Tip podataka koji može da referencira metode sa specifičnim potpisom.
  • Generički delegat: Delegat koji koristi generičke tipove i može se koristiti sa različitim tipovima podataka.
Sintaksa definisanja generičkog delegata:

public delegate T Operation<T>(T a, T b);

  • Operation<T> je generički delegat koji može referencirati metode koje uzimaju dva parametra tipa T i vraćaju rezultat tipa T.
Primer upotrebe generičkog delegata:
  1. Kreiranje delegata i metode:

public class Program
{
public static void Main(string[] args)
{
Operation<int> add = Add;
int result = add(5, 3);
Console.WriteLine(result); // Output: 8
}

public static int Add(int x, int y)
{
return x + y;
}
}

U ovom primeru, generički delegat Operation<int> referencira metodu Add koja sabira dva cela broja.

2. Korišćenje sa različitim tipovima podataka:

public class Program
{
public static void Main(string[] args)
{
Operation<int> addIntegers = Add;
Operation<string> concatenateStrings = Concatenate;

Console.WriteLine(addIntegers(10, 20)); // Output: 30
Console.WriteLine(concatenateStrings("Hello", "World")); // Output: HelloWorld
}

public static int Add(int x, int y)
{
return x + y;
}

public static string Concatenate(string a, string b)
{
return a + b;
}
}

Ovde se generički delegat Operation<T> koristi sa različitim tipovima podataka (int i string).

Korisni generički delegati koji dolaze ugrađeni u C#:
  • Func<T, TResult>: Delegat koji uzima jedan ili više parametara tipa T i vraća rezultat tipa TResult.
  • Action<T>: Delegat koji uzima jedan ili više parametara tipa T i ne vraća vrednost (void).
  • Predicate<T>: Delegat koji uzima jedan parametar tipa T i vraća bool vrednost.
Primer korišćenja Func i Action delegata:
public class Program
{
public static void Main(string[] args)
{
Func<int, int, int> multiply = Multiply;
Action<string> print = PrintMessage;

Console.WriteLine(multiply(3, 4)); // Output: 12
print("Hello, World!"); // Output: Hello, World!
}

public static int Multiply(int x, int y)
{
return x * y;
}

public static void PrintMessage(string message)
{
Console.WriteLine(message);
}
}

Zadaci za učenike:
  1. Implementacija generičkog delegata: Definisati generički delegat koji radi sa listama i implementirati metodu koja koristi taj delegat za filtriranje elemenata liste.
  2. Upotrebiti Func delegat: Napisati program koji koristi Func delegat za različite matematičke operacije (sabiranje, oduzimanje, množenje, deljenje).

  1. Koje su prednosti korišćenja generičkih delegata u odnosu na obične delegate?
  2. Kada bi bilo korisno koristiti Func i Action delegate?
  3. Kako bi se generički delegati mogli koristiti u stvarnim aplikacijama?

Last modified: Tuesday, 2 December 2025, 4:57 AM