2013-07-09 21 views
6

Czytałem MSDN page o delegatach i wydają się proste. Potem patrzyłem na kod, który je wykorzystuje i widziałem to:Co robi ta metoda delegata?

public delegate void NoArguments(); 
public NoArguments Refresh = null; 
Refresh = new NoArguments(Reset); 

To ta trzecia linia, która mnie wprawia w zakłopotanie. Jak możesz new delegata? To nie jest obiekt, to metoda, a raczej delegat do metody. Zgodnie z przykładem na stronie MSDN tworzenie instancji delegata odbywa się poprzez proste przypisanie, a nie przydział. Ponadto, dlaczego jest new dla delegata przyjmującego parametr, Reset, gdy deklaracja delegata nie przyjmuje parametrów?

Odpowiedz

1

Delegat jest "delegatem do metody", ale także obiektem. Jeśli spojrzysz na NoArguments w dowolnym dekompilatorze, zobaczysz, że jest to klasa dziedzicząca po MulticastDelegate, kilkoma metodami (Invoke, BeginInvoke, EndInvoke).

Ze względów historycznych C# umożliwia tworzenie wystąpień tej klasy przy użyciu new NoArguments(method). Jednak we współczesnych wersjach obsługuje również notację skrótu method, która robi to samo. W obu przypadkach faktycznie masz obiekt typu NoArguments w Refresh.

+0

Dzięki za wskazanie, że to rzeczywiście obiekt, a nie tylko wskaźnik funkcji. – johnbakers

4

Słowo kluczowe wskazuje, że to, co następuje, jest w zasadzie podpisem funkcji, dlatego też Refresh staje się czymś w rodzaju wskaźnika do funkcji, która nie przyjmuje żadnych argumentów. Jednak aby przypisać coś do wskaźnika Refresh, musisz dać mu funkcję, na którą wskażemy. W tym przypadku jest to funkcja Reset. Ponadto funkcja Reset nie musi przyjmować żadnych argumentów.

Dodatkowo składnia:

Refresh = Reset; 

jest również ważna, a to po prostu cukier syntaktyczny dla bardziej składni formalnej:

Refresh = new NoArguments(Reset); 

w obu przypadkach, można wtedy wykonać funkcję resetowania pod numerem Odśwież:

Refresh(); 

Pamiętaj jednak, że jeśli wykonasz Refresh() bez przypisania, możesz wygenerować wyjątek. Sposobem na zapobieganie tego byłoby sprawdzić je przed zerową:

if (Refresh != null) Refresh(); 
else { 
    // Refresh was never assigned 
} 
2

można pomyśleć delegat jest jak rodzaj funkcji:

  • typu deklaruje funkcja zwraca void i nie mają argumentów:

    public delegate void NoArguments(); 
    
  • Declare zmienna danego typu i zainicjować go:

    public NoArguments Refresh = null; 
    
  • Przypisz nowy obiekt do swojej zmiennej. Obiekt jest rzeczywiście funkcja Reset, które muszą mieć ten sam podpis jako delegat:

    Refresh = new NoArguments(Reset); 
    

UPDATE:

Możesz przejrzeć poniższy link aby uzyskać więcej informacji: C# Delegates