Die Anleitung zu C# Delegate und Event

1- What is 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
    {
        // This is the method that has a parameter of type string and returns the string
        // Function type: (string) -> (string)
        public string SayHello(string name)
        {
            return "Hello " + name;
        }
        
        // This is the method that has 2 parameter and returns the string
        // Function type:  (string, string) -> (string)
        public string SayHello(string firstName, string lastName)
        {
            return "Hello " + firstName + " " + lastName;
        }

        // This is the method that has a parameter and returns nothing.
        // Function type: (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:
// Syntax to define a delegate:

delegate <return_type> <delegate_name> <parameter_list>
Das Beispiel
// Define a type representing the function type:
// (string,string) -> (string).

private delegate string MyDelegate(string s1, string s2);

2- Delegate examples

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
    {
        // Defining a 'delegate' for the function type:
        // (int, int) -> (int)
        delegate int IntIntToInt(int a, int b);



        public static void Main(string[] args)
        {

            // Create a delegate object
            // Pass a function to it. (Same function type with delegate)
            IntIntToInt iiToInt = new IntIntToInt(MathUtils.sum);

            // Execute a delegate
            // It will call the function (or method) that it represents.
            int value = iiToInt(10, 20); // 30

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

            // Assign other values for delegate
            iiToInt = new IntIntToInt(MathUtils.multiple);

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

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

            Console.Read();

        }


    }


}
Running the example:
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
    {
        // Create a Delegate
        // Representing the type of function: (string) -> (string).
        private delegate string StringStringToString(string s);



        public static void Main(string[] args)  
        {

            // Create HelloProgram object.
            HelloProgram program = new HelloProgram();

            // Create a delegate, represent for sayHello function
            StringStringToString ssToS = new StringStringToString(program.SayHello);


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

            Console.WriteLine(greeting);

            Console.Read();
        }

    }


}

3- Function returns a function

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
    {
        // A delegate representing the type of function: (float) -> (float).
        public delegate float TaxFormula(float salary);

        // US tax calculation formula (10% of salary).
        public static float UsaFormula(float salary)
        {
            return 10 * salary / 100;
        }

        // Vietnam tax calculation formula (5% of salary).
        public static float VietnamFormula(float salary)
        {
            return 5 * salary / 100;
        }
        // Default tax calculation formula (7% of salary).
        public static float DefaultFormula(float salary)
        {
            return 7 * salary / 100;
        }

        // Returns a function to calculate the tax, based on the national code (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;

            // The formula for calculating tax in Vietnam.
            TaxFormulas.TaxFormula formula = TaxFormulas.GetSalaryFormula("VN");

            float tax = formula(salary);

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

            // The formula for calculating tax in Canada.
            formula = TaxFormulas.GetSalaryFormula("CA");

            tax = formula(salary);

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

            Console.Read();
        }
    }

}
Das Beispiel :

4- Anonymous methods

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
    {
        // A delegate representing the type of function: (float) -> (float).
        // Tax calculation based on salary.
        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:

5- Multicasting of a 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
    {
        // Function type:  (String) -> ()
        public static void Hello(String name)
        {
            Console.WriteLine("Hello " + name);
        }

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

        // Function type:  (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
    {
        // Declare a delegate

        public delegate void Greeting(string name);


        public static void Main(string[] args)
        {
            // Create delegate objects.
            Greeting hello = new Greeting(Greetings.Hello);
            Greeting bye = new Greeting(Greetings.Bye);
            Greeting hi = new Greeting(Greetings.Hi);
            
            // Create a delegate (sum of two delegate).

            Greeting greeting = hello + bye;
           
            // You are also using += operator.
            greeting += hi;

            // Gọi thực thi greeting
            greeting("Tom");

            Console.Read();


        }
    }

}
Running the example:

6- What is 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);
       
       // Define an event, It is not assigned value
       // Its value is assigned on the outside.
       public event ClickHander OnButtonClick;

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

       // Called when button clicked.
       // Locate the x, y where users click.
       public void Clicked()
       {
           Random random = new Random();

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

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

           // Fire event
           if (OnButtonClick != null)
           {
               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;
      
       // Simulating an application with the buttons.
       public MyApplication()
       {
           // Add a button to interface
           this.openButton = new Button("Open File");

           // Add a button to interface
           this.saveButton = new Button("Save File");

           // Add method to event of button. ('Open Button')
           // (Multicasting feature of Delegate)
           this.openButton.OnButtonClick += this.OpenButtonClicked;

           // Add method to event of button ('Save Button').
           // (Multicasting feature of Delegate)
           this.saveButton.OnButtonClick += this.SaveButtonClicked;
       }

       private void OpenButtonClicked(Button source, int x, int y)
       {
           // Simulation opens a window to select the file.
           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)
       {
           // Open app
           MyApplication myApp = new MyApplication();

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

           // Click openButton
           myApp.openButton.Clicked();

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

           // Click saveButton.
           myApp.saveButton.Clicked();


           Console.Read();
         
       }
   }

}
 
Running the example: