2013-03-05 8 views
7

Uczę się o delegatach. Kilka dni temu zrobiłem próbkę dla delegatów ds. Multiemisji i przejrzałem tutaj My previous question i jasno zrozumiałem o delegacie multicastowym.Delegat ds. Multiemisji i wydarzenie

Ale teraz próbuję zrobić próbkę delegata multiemisji ze zdarzeniem. Ale mam pewne wątpliwości podczas robienia próbki. W powyższym linku zrobiłem wszystkie funkcje i delegowałem deklarację w jednej klasie i dodałem funkcję do delegowania za pomocą + = i po prostu dzwoń do delegata. A więc wszystkie funkcje wewnątrz delegatów są wywoływane.

Ale teraz robię to w dwóch różnych klasach i próbuję wykonywać wszystkie funkcje przy pomocy zdarzenia. Podaję mój obecny kod poniżej.

public partial class Form1 : Form 
{ 
    public Form1() 
    { 
     InitializeComponent(); 

     ArithmeticOperations aOperations = new ArithmeticOperations(); 
     aOperations.StartCalculations += new ArithmeticOperations.BasicCalculations(aOperations_StartCalculations); 
     aOperations.PerformCalculations(20, 10); 
    } 

    void aOperations_StartCalculations(string msg) 
    { 
     MessageBox.Show(msg); 
    } 
} 


class ArithmeticOperations 
{ 
    public delegate void BasicCalculations(string msg); 

    public event BasicCalculations StartCalculations; 


    public void PerformCalculations(int n1, int n2) 
    { 
     StartCalculations("Operation Success"); 
    } 

    void Add(int num1, int num2) 
    { 
     MessageBox.Show("Performing addition."); 
    } 

    void Sub(int num1, int num2) 
    { 
     MessageBox.Show("Performing substraction."); 
    } 

    void Mul(int num1, int num2) 
    { 
     MessageBox.Show("Performing multiplication."); 
    } 

    void Div(int num1, int num2) 
    { 
     MessageBox.Show("Performing division."); 
    } 

} 

Tutaj w Form1 jest mój główny klasa i klasa ArithmeticOperations używa do wykonywania funkcji. Kiedy o tym stwierdzeniem

aOperations.PerformCalculations(20, 10); 

w Form1, funkcja PerformCalculation() w klasie ArithmeticOperations wykona.

Ale mam wątpliwości, jak zarejestrować wszystkie funkcje Add, Sub, Mul i Div dla delegata w klasie AritmeticOperations, aby wywołać wszystkie funkcje, po prostu wywołując obiekt delegata i zwróć "Operacja Success" do funkcji zwrotnej zdarzenia w Form1 klasa ?

+2

Twój typ delegata 'BasicCalculations' (który jest zagnieżdżony wewnątrz klasy, dlaczego?) ma sig nature 'BasicCalculations (string msg)', więc przyjmuje jeden argument, który jest 'string'. Twoja metoda "Add" itd. Przyjmuje dwa argumenty, oba z nich są "int". Jak więc ta metoda może bezpośrednio pasować do twojego wydarzenia? –

+0

Ups ... Nie widziałem tego ... ur right ... thankx – Arun

Odpowiedz

3

Od BasicCalculations przyjmuje jeden argument typu string, nie może być stosowany bezpośrednio powoływać swoje metody Add, Subtract itp

Jeśli chcesz PerformCalculations do wywołania każdej z metod poprzez multicast, trzeba będzie delegata typu odpowiednik Action<int, int>, np

class ArithmeticOperations 
{ 
    public delegate void BasicCalculations(string msg); 

    public event BasicCalculations StartCalculations; 

    private Action<int, int> calculations; 

    public ArithmeticOperations() 
    { 
     this.calculations += this.Add; 
     this.calculations += this.Sub; 
    } 

    public void PerformCalculations(int n1, int n2) 
    { 
     this.calculations.Invoke(n1, n2); 
     StartCalculations("Operation Success"); 
    } 

    // ... 
} 

Jeśli chcesz, aby twoje indywidualne metody obliczeniowe powołać wydarzenie StartCalculations sznurkiem, można pozwolić im zrobić to tak:

void Add(int num1, int num2) 
{ 
    StartCalculations("Performing addition."); 
} 

Podczas podnoszenia zdarzenia, należy sprawdzić, czy istnieją abonenci pierwszy (aby uniknąć NullReferenceException). standard pattern polega na subskrypcji dowolnego programu obsługi, przetestowaniu pod kątem null, a następnie wywołaniu programu obsługi. Pozwoli to na uniknięcie trafienia NullReferenceException, jeśli ktoś unsubscribes po testowaniu imprezie null:

void Add(int num1, int num2) 
{ 
    var handler = this.StartCalculations; 
    if (handler != null) 
    { 
     handler("Performing addition."); 
    } 
} 

Ponieważ to byłoby dużo kodu powtórzenia dla każdej metody, można byłaby go w osobnej metody:

void Add(int num1, int num2) 
{ 
    this.OnStartCalculation("Performing addition."); 
} 

void OnStartCalculation(string message) 
{ 
    var handler = this.StartCalculations; 
    if (handler != null) 
    { 
     handler(message); 
    } 
} 
+0

Dzięki Ergwun. Teraz zrozumiałem. Pierwszy raz słyszę o tym działaniu <>. Dziękuję za dodatkowe informacje. – Arun

+0

Jeszcze raz dziękuję za udzielenie dodatkowych informacji.:) – Arun

3

jedną z opcji byłoby stworzenie prywatną imprezę

public delegate void BasicCalculations(string msg); 

public delegate void DoMath(int na, int nb); 
class ArithmeticOperations 
{ 
    public ArithmeticOperations() 
    { 
     StartMath += new DoMath(ArithmeticOperations_StartMath); 

    } 

    void ArithmeticOperations_StartMath(int na, int nb) 
    { 
     Add(na, nb); 
     Sub(na, nb); 
     Mul(na, nb); 
     Div(na,nb); 
    } 




    public event BasicCalculations StartCalculations; 
    private event DoMath StartMath; 

    public void PerformCalculations(int n1, int n2) 
    { 
     StartMath(n1, n2); 
     StartCalculations("Operation Success"); 
    } 

    void Add(int num1, int num2) 
    { 
     Console.WriteLine("Performing addition."); 
    } 

    void Sub(int num1, int num2) 
    { 
     Console.WriteLine("Performing substraction."); 
    } 

    void Mul(int num1, int num2) 
    { 
     Console.WriteLine("Performing multiplication."); 
    } 

    void Div(int num1, int num2) 
    { 
     Console.WriteLine("Performing division."); 
    } 

} 
+0

Dziękuję saurabh. Twoja sugestia również pomaga mi ją dobrze zrozumieć. Dzięki – Arun