376 Stimmen

Was sind die Unterschiede zwischen Delegierten und Veranstaltungen?

Was sind die Unterschiede zwischen Delegierten und einem Ereignis? Enthalten nicht beide Verweise auf Funktionen, die ausgeführt werden können?

6voto

Weidong Shen Punkte 39

Delegate ist ein typsicherer Funktionszeiger. Event ist eine Implementierung des Publisher-Subscriber-Designmusters unter Verwendung von Delegaten.

5voto

Paul Hill Punkte 85

Sie können Ereignisse auch in Schnittstellendeklarationen verwenden, nicht so bei Delegierten.

4voto

supercat Punkte 72939

Ein Ereignis in .net ist eine bestimmte Kombination aus einer Add-Methode und einer Remove-Methode, die beide einen bestimmten Typ von Delegaten erwarten. Sowohl C# als auch VB.net können automatisch Code für die Add- und Remove-Methoden generieren, der einen Delegaten für die Ereignisabonnements definiert und den übergebenen Delegaten zu diesem Abonnementdelegaten hinzufügt bzw. von diesem entfernt. VB.net generiert auch automatisch Code (mit der Anweisung RaiseEvent), um die Abonnementliste aufzurufen, wenn und nur wenn es nicht leer ist; aus irgendeinem Grund, C# generiert letzteres nicht.

Beachten Sie, dass es zwar üblich ist, Ereignisabonnements mit einem Multicast-Delegaten zu verwalten, dies aber nicht die einzige Möglichkeit ist. Aus der Sicht der Öffentlichkeit muss ein potenzieller Ereignisabonnent wissen, wie er ein Objekt wissen lässt, dass er Ereignisse empfangen möchte, aber er muss nicht wissen, welchen Mechanismus der Herausgeber verwenden wird, um die Ereignisse auszulösen. Beachten Sie auch, dass derjenige, der die Ereignisdatenstruktur in .net definiert hat, offenbar der Meinung war, dass es ein öffentliches Mittel zum Auslösen von Ereignissen geben sollte, aber weder C# noch vb.net machen von dieser Möglichkeit Gebrauch.

2voto

Die Definition eines Ereignisses ist einfach:

Veranstaltung ist eine REFERENZ an einen Delegierten mit zwei Einschränkungen

  1. Kann nicht direkt aufgerufen werden
  2. Kann nicht direkt mit Werten belegt werden (z.B. eventObj = delegateMethod)

Die beiden oben genannten Punkte sind die Schwachstellen der Delegierten und werden in der Veranstaltung angesprochen. Ein vollständiges Codebeispiel, das den Unterschied in Fiddler zeigt, finden Sie hier https://dotnetfiddle.net/5iR3fB .

Schalten Sie den Kommentar zwischen Ereignis und Delegat und Client-Code, der den Delegaten Werte zuweist, um den Unterschied zu verstehen

Hier ist der Inline-Code.

 /*
This is working program in Visual Studio.  It is not running in fiddler because of infinite loop in code.
This code demonstrates the difference between event and delegate
        Event is an delegate reference with two restrictions for increased protection

            1. Cannot be invoked directly
            2. Cannot assign value to delegate reference directly

Toggle between Event vs Delegate in the code by commenting/un commenting the relevant lines
*/

public class RoomTemperatureController
{
    private int _roomTemperature = 25;//Default/Starting room Temperature
    private bool _isAirConditionTurnedOn = false;//Default AC is Off
    private bool _isHeatTurnedOn = false;//Default Heat is Off
    private bool _tempSimulator = false;
    public  delegate void OnRoomTemperatureChange(int roomTemperature); //OnRoomTemperatureChange is a type of Delegate (Check next line for proof)
    // public  OnRoomTemperatureChange WhenRoomTemperatureChange;// { get; set; }//Exposing the delegate to outside world, cannot directly expose the delegate (line above), 
    public  event OnRoomTemperatureChange WhenRoomTemperatureChange;// { get; set; }//Exposing the delegate to outside world, cannot directly expose the delegate (line above), 

    public RoomTemperatureController()
    {
        WhenRoomTemperatureChange += InternalRoomTemperatuerHandler;
    }
    private void InternalRoomTemperatuerHandler(int roomTemp)
    {
        System.Console.WriteLine("Internal Room Temperature Handler - Mandatory to handle/ Should not be removed by external consumer of ths class: Note, if it is delegate this can be removed, if event cannot be removed");
    }

    //User cannot directly asign values to delegate (e.g. roomTempControllerObj.OnRoomTemperatureChange = delegateMethod (System will throw error)
    public bool TurnRoomTeperatureSimulator
    {
        set
        {
            _tempSimulator = value;
            if (value)
            {
                SimulateRoomTemperature(); //Turn on Simulator              
            }
        }
        get { return _tempSimulator; }
    }
    public void TurnAirCondition(bool val)
    {
        _isAirConditionTurnedOn = val;
        _isHeatTurnedOn = !val;//Binary switch If Heat is ON - AC will turned off automatically (binary)
        System.Console.WriteLine("Aircondition :" + _isAirConditionTurnedOn);
        System.Console.WriteLine("Heat :" + _isHeatTurnedOn);

    }
    public void TurnHeat(bool val)
    {
        _isHeatTurnedOn = val;
        _isAirConditionTurnedOn = !val;//Binary switch If Heat is ON - AC will turned off automatically (binary)
        System.Console.WriteLine("Aircondition :" + _isAirConditionTurnedOn);
        System.Console.WriteLine("Heat :" + _isHeatTurnedOn);

    }

    public async void SimulateRoomTemperature()
    {
        while (_tempSimulator)
        {
            if (_isAirConditionTurnedOn)
                _roomTemperature--;//Decrease Room Temperature if AC is turned On
            if (_isHeatTurnedOn)
                _roomTemperature++;//Decrease Room Temperature if AC is turned On
            System.Console.WriteLine("Temperature :" + _roomTemperature);
            if (WhenRoomTemperatureChange != null)
                WhenRoomTemperatureChange(_roomTemperature);
            System.Threading.Thread.Sleep(500);//Every second Temperature changes based on AC/Heat Status
        }
    }

}

public class MySweetHome
{
    RoomTemperatureController roomController = null;
    public MySweetHome()
    {
        roomController = new RoomTemperatureController();
        roomController.WhenRoomTemperatureChange += TurnHeatOrACBasedOnTemp;
        //roomController.WhenRoomTemperatureChange = null; //Setting NULL to delegate reference is possible where as for Event it is not possible.
        //roomController.WhenRoomTemperatureChange.DynamicInvoke();//Dynamic Invoke is possible for Delgate and not possible with Event
        roomController.SimulateRoomTemperature();
        System.Threading.Thread.Sleep(5000);
        roomController.TurnAirCondition (true);
        roomController.TurnRoomTeperatureSimulator = true;

    }
    public void TurnHeatOrACBasedOnTemp(int temp)
    {
        if (temp >= 30)
            roomController.TurnAirCondition(true);
        if (temp <= 15)
            roomController.TurnHeat(true);

    }
    public static void Main(string []args)
    {
        MySweetHome home = new MySweetHome();
    }

}

2voto

Rainning Punkte 1

Für Menschen, die im Jahr 2020 leben und eine saubere Antwort wollen...

Definitionen:

  • delegate : definiert einen Funktionszeiger.
  • event : definiert
    • (1) geschützt Schnittstellen,
    • (2) Operationen( += , -= ),
    • (3) Vorteil: Sie müssen nicht die new Stichwort nicht mehr.

Bezüglich des Adjektivs geschützt :

// eventTest.SomeoneSay = null;              // Compile Error.
// eventTest.SomeoneSay = new Say(SayHello); // Compile Error.

Beachten Sie auch diesen Abschnitt von Microsoft: https://docs.microsoft.com/en-us/dotnet/standard/events/#raising-multiple-events

Code-Beispiel:

avec delegate :

public class DelegateTest
{
    public delegate void Say(); // Define a pointer type "void <- ()" named "Say".
    private Say say;

    public DelegateTest() {
        say  = new Say(SayHello);     // Setup the field, Say say, first.
        say += new Say(SayGoodBye);

        say.Invoke();
    }

    public void SayHello() { /* display "Hello World!" to your GUI. */ }
    public void SayGoodBye() { /* display "Good bye!" to your GUI. */ }
}

avec event :

public class EventTest
{
    public delegate void Say();
    public event Say SomeoneSay;  // Use the type "Say" to define event, an 
                                  // auto-setup-everything-good field for you.
    public EventTest() {
         SomeoneSay += SayHello;
         SomeoneSay += SayGoodBye;

         SomeoneSay();
    }

    public void SayHello() { /* display "Hello World!" to your GUI. */ }
    public void SayGoodBye() { /* display "Good bye!" to your GUI. */ }
}

Referenz:

Ereignis vs. Delegierter - Erläuterung der wichtigen Unterschiede zwischen dem Ereignis- und dem Delegate-Muster in C# und warum sie nützlich sind. : https://dzone.com/articles/event-vs-delegate

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X