codestory

Die Anleitung zu C# Delegate und Event

  1. Was ist Delegate?
  2. Das Beispiel mit delegate
  3. Die Funktion gibt eine Funktion rück
  4. Die anonyme Methoden
  5. Multicasting von einer Delegate
  6. Was ist Event?

1. Was ist Delegate?

Im C# hat jede Funktion (Die Methode, oder constructor) eine eigene Funktionstyp. Bitte sehen Sie die Methode SayHello wie folgend:
Sehen Sie das volle Beispiel:
HelloProgram.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CSharpDelegatesTutorial
{
    class HelloProgram
    { 
        // Das ist eine Methode mit einem String Parameter und string zurückgeben
        // Das Funktionstyp:  (string) -> (string)
        public string SayHello(string name)
        {
            return "Hello " + name;
        }
        
        // Das ist eine Methode mit 2 tring Parameters und string zurückgeben
        // Das Funktionstyp: (string, string) -> (string)
        public string SayHello(string firstName, string lastName)
        {
            return "Hello " + firstName + " " + lastName;
        }

        // Das ist eine Methode mit einem Parameter und nichts zurückgeben
        // Das Funktionstyp: (string) -> ()
        public void Silent(string name)
        {

        }
    }


}
Die 2 unten Methode haben die gleichen Funktionstype
C# benutzt das Schlüsselwort delegate (der Vertreter) um eine Vertretungenttät für die Funktionen (die Methode, oder constructor) mit einem gleichen Typ zu definieren.
Die Syntax:
// Die Syntax definiert eine  delegate:
delegate <return_type> <delegate_name> <parameter_list>
Das Beispiel
// Die Definition eines Typ, 
// das die Funktion mit dem Typ von (string,string) -> (string) vertritt.
private delegate string MyDelegate(string s1, string s2);

2. Das Beispiel mit delegate

MathUtils.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CSharpDelegatesTutorial
{
    class MathUtils
    {

        // (int, int)  -> (int)
        public static int sum(int a, int b)
        {
            return a + b;
        }

        // (int, int)  -> (int)
        public static int minus(int a, int b)
        {
            return a - b;
        }

        // (int, int)  -> (int)
        public static int multiple(int a, int b)
        {
            return a * b;
        }
 

    }

}
Das folgende Beispiel bezeichnet die Definition einer delegate IntIntToInt , die die Funktion mit der Typ (int, int) -> (int) vertretet.
MyFirstDelegate.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CSharpDelegatesTutorial
{
    class MyFirstDelegate
    {
        // Eine Delagate, die die Funktion mit dem Typ vom (int, int) -> (int) definieren
        delegate int IntIntToInt(int a, int b);



        public static void Main(string[] args)
        {
            // Das Objekt Delegate erstellen.
            // In den Parameter eine Funktion mit dem gleichen Typ vom delegate übertragen (pass).
            IntIntToInt iiToInt = new IntIntToInt(MathUtils.sum);

            // Wenn Sie ein Delegate durchführen, 
            // wird es die Funktion oder die MEthode, die es vertritt, aufrufen.
            int value = iiToInt(10, 20); // 30

            Console.WriteLine("Value = {0}", value);

            // Die andere Wert für Delegate übertragen
            iiToInt = new IntIntToInt(MathUtils.multiple);

            value = iiToInt(10, 20); // 200

            Console.WriteLine("Value = {0}", value);

            Console.Read();

        }


    }


}
das Beispiel durchführen
Value = 30
Value = 200
SIe können ein Objekt Delegate erstellen , das die none static Funktion vertretet. Sehen Sie das Beispiel:
HelloProgramTest.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CSharpDelegatesTutorial
{
    class HelloProgramTest
    {
        // Ein Delegate, das die Funktion mit dem Typ (string) -> (string) vertritt, erstellen.
        private delegate string StringStringToString(string s);



        public static void Main(string[] args)  
        {

            // Das Objekt HelloProgram erstellen
            HelloProgram program = new HelloProgram();

            // Ein Objekt Delegate zur Vertretung der Funktion SayHello erstellen.
            StringStringToString ssToS = new StringStringToString(program.SayHello);


            // Test 
            string greeting = ssToS("Tom");

            Console.WriteLine(greeting);

            Console.Read();
        }

    }


}

3. Die Funktion gibt eine Funktion rück

Im C# können Sie mit Delegate eine Funktion, die eine Funktion zurückgibt, erstellen (pratisch gibt eine Funktion eine Delegate zurück).
TaxFormulas.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CSharpDelegatesTutorial
{
    class TaxFormulas
    {
        // Ein Delegate zur Vertretung der Funktion mit dem Typ vom (float) -> (float).
        public delegate float TaxFormula(float salary);

        // Die Formel zur Steuerkalkulation von USA (10% des Gehalt).
        public static float UsaFormula(float salary)
        {
            return 10 * salary / 100;
        }

        // Die Formel zur Steuerkalkulation von Vietnam (5% des Gehalt).
        public static float VietnamFormula(float salary)
        {
            return 5 * salary / 100;
        }

        // Die Default-Formel zur Steuerkalkulation (7% des Gehalt).
        public static float DefaultFormula(float salary)
        {
            return 7 * salary / 100;
        }

        // Eine Funktion zur Steuerkalkulation nach der Staatcode zurückgeben. (VN, USA, ..)
        public static TaxFormula GetSalaryFormula(string countryCode)
        {
            if (countryCode == "VN")
            {
                return TaxFormulas.VietnamFormula;
            }
            else if (countryCode == "USA")
            {
                return TaxFormulas.UsaFormula;
            }
            return TaxFormulas.DefaultFormula;
        }

    }

}
TaxFormulaTest.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CSharpDelegatesTutorial
{
    class TaxFormulaTest
    {


        public static void Main(string[] args)
        {
            float salary = 1000f;

            // Die Formel zur Steuerkalkulation nach der Staat Vietnam.
            TaxFormulas.TaxFormula formula = TaxFormulas.GetSalaryFormula("VN");

            float tax = formula(salary);

            Console.WriteLine("Tax in Vietnam = {0}", tax);

            // Die Formel zur Steuerkalkulation bei Canada
            formula = TaxFormulas.GetSalaryFormula("CA");

            tax = formula(salary);

            Console.WriteLine("Tax in Canada = {0}", tax);

            Console.Read();
        }
    }

}
Das Beispiel durchführen:
Tax in Vietname = 50
Tax in Canada = 70

4. Die anonyme Methoden

Nach der Delegate können Sie eine anonymous Methode erstellen. Das ist eine Methode, die keinen Name aber nur das Body der Methode hat. Das ist ein Befehlblock mit 0 oder viele Parameter.
AnonymousMethod.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CSharpDelegatesTutorial
{
    class AnonymousMethod
    {
        // Ein Delegate vertritt die Funktion mit dem Typ : (float) -> (float).
        // Die Steuerkalkukation nach des Gehalt
        public delegate float TaxFormula(float salary);


        public static TaxFormula GetTaxFormula(string countryCode)
        {
            if ("USA" == countryCode)
            {
                TaxFormula usaFormula = delegate(float salary)
                {
                    return 10 * salary / 100;
                };
                return usaFormula;
            }
            else if ("VN" == countryCode)
            {
                TaxFormula vnFormula = delegate(float salary)
                {
                    return 5 * salary / 100;
                };
                return vnFormula;
            }
            return delegate(float salary)
            {
                return 7 * salary / 100;
            };
        }


        public static void Main(string[] args)
        {
            string countryCode = "VN";
            float salary = 1000;

            TaxFormula formula = GetTaxFormula(countryCode);

            float tax = formula(salary);

            Console.WriteLine("countryCode = {0}, salary = {1} -> tax = {2}"
                                    , countryCode, salary, tax);

            Console.Read();
        }
    }

}
Das Beispiel durchführen:
countryCode = VN, salary = 1000 -> tax = 50

5. Multicasting von einer Delegate

C# genehmigt Sie bei der Zusammenrechnung von 2 Objekt Delegate um zu einem neuen Objekt Delegate zu werden. Beachten Sie, Sie können die Objekt Delegate nur zusammenrechnen wenn sie die gleichen Funktion haben und die Funktion hat kein Rückgabewert. Wenn ein neues Objekt Delegate geruft wird, werden alle untergeordneten Delegate auch durchgeführt. Der Begriff wird als Multicasting von delegate genannt.
Greetings.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CSharpDelegatesTutorial
{
    class Greetings
    {
        // Das Funktionstyp: (String) -> ()
        public static void Hello(String name)
        {
            Console.WriteLine("Hello " + name);
        }

        // Das Funktionstyp: (String) -> ()
        public static void Bye(string name)
        {
            Console.WriteLine("Bye " + name);
        }

        // Das Funktionstyp: (String) -> ()
        public static void Hi(string name)
        {
            Console.WriteLine("Hi " + name);
        }
    }

}
MulticastingTest.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CSharpDelegatesTutorial
{
    class MulticastingTest
    {
        // Ein Delegate erklären.
        public delegate void Greeting(string name);


        public static void Main(string[] args)
        {
            // Das Objekte Delegate erstellen.
            Greeting hello = new Greeting(Greetings.Hello);
            Greeting bye = new Greeting(Greetings.Bye);
            Greeting hi = new Greeting(Greetings.Hi);
            
            // Ein Delegate als die Kollektion von 3 obengemeinten Objekte erstellen.
            Greeting greeting = hello + bye;
           
            // Sie können den Operator += benutzen
            greeting += hi;

            // Die Durchführung von greeting.
            greeting("Tom");

            Console.Read();


        }
    }

}
Das Beispiel durchführen
Hello Tom
Bye Tom
Hi Tom

6. Was ist Event?

Im C# ist Event ein besonderes Objekt von Delegate. Es enthaltet die Methode. und diese Methode werden gleichzeitig durchgeführt wenn Event passiert. Sie können die Methode in das Objekt Event hinzufügen.
Example:
Die Klasse Button bezeichnet einen Button. Sie definiert ein Event zu informieren, dass sie geklickt wird. Wenn ein Button geklickt wird, wird Event durchgeführt. Sie brauchen mehr Methode für das Objekt Event hinzufügen
Button.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CSharpEventsTutorial
{
    class Button
    {

        private string label;

        public delegate void ClickHander(Button source, int x, int y);

        // Die Definition eines Event. Es wird noch die Wert nicht übergetragen. 
        // Seine Wert wird vom außen übergetragen.
        public event ClickHander OnButtonClick;

        public Button(string label)
        {
            this.label = label;
        }

        // IDie Illustration : die Button wird geklickt (Click).
        // Die Stelle von x, y, die der Benutzer klickt, bestimmen.
        public void Clicked()
        {
            Random random = new Random();

            // Eine Random Zahl vom  1 -> 100
            int x = random.Next(1, 100);

            // Eine Random Zahl vom 1 -> 20
            int y = random.Next(1, 20);


            if (OnButtonClick != null)
            {
                // Die Aufruf auf die Event-Behandlung
                OnButtonClick(this, x, y);
            }
            
        }
    }


}
Die Klasse MyApplication bezeichnet eine Applikation mit 2 Button , "Open File" und "Save File".

Sie sollen die Methode schreiben um etwas zu machen wenn der Benutzer auf "Open File" klicken, und Fügen Sie die Methode in Event OnButtonClick des Buttons openButton hinzu

Sie sollen die Methode schreiben um etwas zu machen wenn der Benutzer auf "Save File" klicken, und fügen Sie die Methode in Event OnButtonClick des Buttons saveButton.
MyApplication.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CSharpEventsTutorial
{
    class MyApplication
    {
        private Button openButton;
        private Button saveButton;
        private string fileName;

        // Eine Applikation mit der Button simulieren.
        public MyApplication()
        {
            // Eine Button in der Interface einfügen.
            this.openButton = new Button("Open File");

            // Eine Button in der Interface einfügen.
            this.saveButton = new Button("Save File");

            // Eine Methode ins Event von Button 'Open Button'.
            // (Die Funktion Multicasting von Delegate)
            this.openButton.OnButtonClick += this.OpenButtonClicked;

            // Eine Methode ins Event von Button 'Save Button'.
            // (Die Funktion Multicasting von Delegate)
            this.saveButton.OnButtonClick += this.SaveButtonClicked;
        }

        private void OpenButtonClicked(Button source, int x, int y)
        {
            // Die Öffnung eines Fenster simulieren um die File zur Öffnung zu wählen
            Console.WriteLine("Open Dialog to Select a file");
            // 
            this.fileName = "File" + x + "_" + y+".txt";
            Console.WriteLine("Openning file: "+ this.fileName);
        }

        private void SaveButtonClicked(Button source, int x, int y)
        {
            if(this.fileName== null)  {
                Console.WriteLine("No file to save!");
                return;
            }
            // Save File
            Console.WriteLine("Saved file: " + this.fileName);
        }
 

        public static void Main(string[] args)
        {

            // Die Öffnung der Applikation simulieren
            MyApplication myApp = new MyApplication();

            Console.WriteLine("User Click on Open Button ....");

            // Die Simulation vom geklickten openButton 
            myApp.openButton.Clicked();

            Console.WriteLine("\n\n");
            Console.WriteLine("User Click on Save Button ....");

            // Die Simulation vom geklickten saveButton 
            myApp.saveButton.Clicked();


            Console.Read();
            
        }
    }

}
Das Beispiel durchführen
User Click on Open Button ....
Open Dialog to Select a file
Openning file: File75_4.txt

User Click on Save Button ....
Saved file: File75_4.txt