FER / ZPR /  Ergonomija
Svojstva Događaji
Za napredne
Multithreaded Programming using C# je članak o višenitnom programiranju koje nam omogućuje da radimo aplikacije koje bolje iskorištavaju procesorske resurse. Pri tome trebamo biti oprezni i znati kada korisiti ova svojstva jer može doći i do suprotnog učinka.

» Pročitaj članak

Delegati

Delegat je tip za referenciranje metoda. Kada se delegat pridruži metodi, ponaša se isto kao i ta metoda. Može se koristiti kao i svaka metoda, sa parametrima i povratnom vrijednosti.
public delegate void Del(string message);
Gora je navedena jedna definicija delegata. Svaka metoda koja odgovara potpisu delegata, koji se sastoji od povratnog tipa i parametara, se može pridružiti delegatu.

Ovo svojstvo da se metoda koristi kao parametar čini delegate idealnim za definiranje callback metoda. Na primjer, sort algoritam može primiti referencu na metodu koja uspoređuje dva objekta. Odvajanjem koda za usporedbu omogućuje algoritmu da se može iskoristiti za više tipova objekata.

Delegat objekt se obično gradi tako što se navede ime metode koji će delegat predstavljati. Kad se delegat instancira, poziv delegata se prosljeđuje metodi. Parametri koji su predani delegatu se daju metodi, isto tako se povratna vrijednost metode vraća delegatu. Delegat se u principu ponaša kao i metoda na koju je vezan. Primjer:
// Create a method for a delegate.
public static void DelegateMethod(string message)
{
    System.Console.WriteLine(message);
}

// Instantiate the delegate.
Del handler = DelegateMethod;

// Call the delegate.
handler("Hello World");
Delegat tipovi se izvode iz Delegate klase .NET Frameworka. Delegate tipovi su sealed (ne mogu se naslijediti) pa nije moguće izvesti custom klasu iz Delegate klase. Zato što su instancirani delegati objekti, mogu se proslijediti kao parametar ili pridružiti nekom svojstvu. Ovo omogućuje metodama da prime delegata kao parametar i da ga pozovu kasnije. Ovo se obično zove asinkroni povratni poziv i predstavlja tipičnu metodu kako obavijestiti pozivatelja kad neki dugotrajni proces završi. Kad je delegat korišten na ovaj način, kod koji koristi delegata ne mora znati koja je metoda povezana uz delegat. Funkcionalnost je slična enkapsulaciji koju sučelja pružaju.

Primjer kada predajemo delegat kao parametar nekoj metodi:
public void MethodWithCallback(int param1, int param2, Del callback)
{
    callback("The number is: " + (param1 + param2).ToString());
}
Sada možemo predati delegat koji smo stvorili u prethodnom primjeru:
MethodWithCallback(1, 2, handler);
Kada je delegat stvoren da obuhvati metodu instance, delegat referencira i metodu i referencu. Delegat ne zna koji je tip instance koju referencira, samo metodu koju sadrži ta instanca i da potpisom odgovara delegatu. Kada delegat predstavlja static metodu, onda referencira samo metodu. Pogledajte sljedeći primjer:
public class MethodClass
{
    public void Method1(string message) { }
    public void Method2(string message) { }
}
Sada sa static metodom DelegateMethod od prije, imamo tri metode koje se mogu obuhvatiti sa Del instancom.

Delegat može pozvati više od jedne metode. Ovo se zove multicasting. Da bi dodali ekstra metodu delegatovoj listi metoda koje poziva (invocation list), koristimo + ili += operatore:
MethodClass obj = new MethodClass();
Del d1 = obj.Method1;
Del d2 = obj.Method2;
Del d3 = DelegateMethod;

//Both types of assignment are valid.
Del allMethodsDelegate = d1 + d2;
allMethodsDelegate += d3;
Sada allMethodsDelegate sadrži tri metode u svojoj liti - Method1, Method2 i DelegateMethod. Originalna tri delegata d1, d2, i d3 ostaju nepromijenjeni. Kad se pozove allMethodsDelegate, sve tri metode se pozivaju redom. Ako delegat koristi reference parametre, referenca se predaje redom svakoj metodi i svaka promjena koju napravi jedna metoda je vidljiva u sljedećoj. Ako neka metoda baci iznimku koja nije obrađena unutar metode, ta iznimka se predaje pozivatelju delegata i ostale metode u listi od delegata se ne pozivaju. Ako delegat ima povratnu vrijednost ili izlazne parametre, vraćaju se povratna vrijednost i parametri zadnje pozvane metode. Da bi neku metodu izbacili iz pozivne liste delegata, koristimo - ili -= operatore:
//remove Method1
allMethodsDelegate -= d1;

// copy AllMethodsDelegate while removing d2
Del oneMethodDelegate = allMethodsDelegate - d2;

Kovarijanca i kontravarijanca

Kovarijanca i kontravarijanca pružaju određen stupanj fleksibilnosti kada određujemo podudarnost potpisa metode i delegata. Kovarijanca omogućuje metodi da koristi izvedeni povratni tip kod delegata, a kontravarijanca omogućuje da se metoda koristi kao delegat čiji su parametri tipa koji je izveden od onih u potpisu metode.

Primjer kovarijance:
class Mammals
{
}

class Dogs : Mammals
{
}

class Program
{
    // Define the delegate.
    public delegate Mammals HandlerMethod();

    public static Mammals FirstHandler()
    {
        return null;
    }

    public static Dogs SecondHandler()
    {
        return null;
    }

    static void Main()
    {
        HandlerMethod handler1 = FirstHandler;

        // Covariance allows this delegate.
        HandlerMethod handler2 = SecondHandler;
    }
}
Primjer kontravarijance:
class Mammals
{
}

class Dogs : Mammals
{
}

class Program
{
    public delegate void HandlerMethod(Dogs sampleDog);

    public static void FirstHandler(Mammals elephant)
    {
    }

    public static void SecondHandler(Dogs sheepDog)
    {
    }

    static void Main(string[] args)
    {
        // Contravariance permits this delegate.
        HandlerMethod handler1 = FirstHandler;

        HandlerMethod handler2 = SecondHandler;
    }
}

na vrh

Svojstva Događaji

 
Copyright © 2006, Mario Bošnjak