Delegeler ve etkinlikler arasındaki farklar nelerdir?


Yanıtlar:


283

Bir olay bildirimi üzerine soyutlama ve koruma katmanı ekler temsilci örneği. Bu koruma, delege istemcilerinin delege ve çağırma listesini sıfırlamasını önler ve yalnızca çağırma listesine hedef eklemeye veya listeden hedef kaldırmaya izin verir.


44
Elbette, bu koruma katmanı ayrıca "istemcilerin" (tanımlayıcı sınıf / yapı dışındaki kod) temsilciyi çağırmasını ve herhangi bir şekilde temsilci nesnesinin olayın arkasındaki "nesneyi" almasını engeller .
Jeppe Stig Nielsen

7
Tamamen doğru değil. Arka uç temsilci örneği olmadan bir olay bildirebilirsiniz. C # 'da, bir etkinliği açıkça uygulayabilir ve istediğiniz farklı bir arka uç veri yapısı kullanabilirsiniz.
Miguel Gamboa

3
@mmcdole açıklamak için bir örnek verebilir misiniz?
vivek nuna

103

Farklılıkları anlamak için bu 2 örneğe bakabilirsiniz

Delegelerle örnek (bu durumda bir Eylem - bir değer döndürmeyen bir tür delege)

public class Animal
{
    public Action Run {get; set;}

    public void RaiseEvent()
    {
        if (Run != null)
        {
            Run();
        }
    }
}

Temsilciyi kullanmak için şöyle bir şey yapmalısınız:

Animal animal= new Animal();
animal.Run += () => Console.WriteLine("I'm running");
animal.Run += () => Console.WriteLine("I'm still running") ;
animal.RaiseEvent();

Bu kod iyi çalışıyor, ancak bazı zayıf noktalarınız olabilir.

Örneğin, bunu yazarsam:

animal.Run += () => Console.WriteLine("I'm running");
animal.Run += () => Console.WriteLine("I'm still running");
animal.Run = () => Console.WriteLine("I'm sleeping") ;

kodun son satırı ile, sadece bir eksik önceki davranışları geçersiz kıldı +( =yerine kullandım +=)

Başka bir zayıf nokta da kullanan her sınıf olmasıdır Animalsınıfını yükseltebilirsiniz RaiseEventçağırarak sadece animal.RaiseEvent().

Bu zayıf noktaları önlemek için eventsc # ' da kullanabilirsiniz .

Hayvan sınıfınız şu şekilde değişecektir:

public class ArgsSpecial : EventArgs
{
    public ArgsSpecial (string val)
    {
        Operation=val;
    }

    public string Operation {get; set;}
} 

public class Animal
{
    // Empty delegate. In this way you are sure that value is always != null 
    // because no one outside of the class can change it.
    public event EventHandler<ArgsSpecial> Run = delegate{} 

    public void RaiseEvent()
    {  
         Run(this, new ArgsSpecial("Run faster"));
    }
}

olayları aramak

 Animal animal= new Animal();
 animal.Run += (sender, e) => Console.WriteLine("I'm running. My value is {0}", e.Operation);
 animal.RaiseEvent();

farklılıklar:

  1. Genel bir mülk değil, genel bir alan kullanıyorsunuz (olayları kullanarak, derleyici alanlarınızı istenmeyen erişimden korur)
  2. Olaylar doğrudan atanamaz. Bu durumda, davranışı geçersiz kılmakla gösterdiğim bir önceki hataya neden olmaz.
  3. Sınıfınızın dışında hiç kimse etkinliği kaldıramaz.
  4. Olaylar bir arabirim bildirimine dahil edilebilir, ancak bir alan

Notlar:

EventHandler aşağıdaki temsilci olarak ilan edildi:

public delegate void EventHandler (object sender, EventArgs e)

bir gönderen (Nesne türü) ve olay bağımsız değişkenleri alır. Statik yöntemlerden geliyorsa gönderen boştur.

Bu örnek, bunun yerine EventHandler<ArgsSpecial>kullanılarak da yazılabilir EventHandler.

EventHandler ile ilgili belgeler için buraya bakın


7
Ben "Sınıfınızın dışında hiç kimse olayı gündeme getiremez." Bu ne anlama geliyor? RaiseEventBir arama yönteminin, animalolayı kullanan koddaki bir örneğine erişimi olduğu sürece kimse arama yapamaz mı?
dance2die

11
@Güncel Olaylar sadece sınıfın içinden yükselebilir, belki bunu açıklayamadım. Olaylarda, olayı yükselten işlevi (kapsülleme) çağırabilirsiniz, ancak yalnızca onu tanımlayan sınıfın içinden yükselebilir. Eğer net değilsem bana haber ver.
faby

1
"Etkinlikler doğrudan atanamaz." Seni yanlış anlayamadıkça, bu doğru değil. İşte bir örnek: gist.github.com/Chiel92/36bb3a2d2ac7dd511b96
ten

2
@faby, Yani etkinlik herkese açık olarak bildirilse bile yine de yapamam animal.Run(this, new ArgsSpecial("Run faster");?
Pap

1
@ChieltenBrinke Tabii ki olay sınıf üyeleri içinde atanabilir ... ama başka türlü olamaz.
Jim Balter

94

Sözdizimsel ve operasyonel özelliklere ek olarak, anlamsal bir fark da vardır.

Delegeler, kavramsal olarak işlev şablonlarıdır; yani, delegenin "türü" olarak değerlendirilmek için bir işlevin uyması gereken bir sözleşmeyi ifade ederler.

Olaylar ... olayları temsil eder. Bir şey olduğunda birini uyarmak için tasarlanmıştır ve evet, bir delege tanımına bağlı kalırlar, ancak aynı şey değildirler.

Tam olarak aynı şey olsalar bile (sözdizimsel olarak ve IL kodunda) anlamsal farklılık olmaya devam edecektir. Genel olarak, aynı şekilde uygulansalar bile, iki farklı kavram için iki farklı isme sahip olmayı tercih ederim (bu, aynı koda iki kez sahip olmayı sevdiğim anlamına gelmez).


8
Delegelerin mükemmel açıklaması.
Sampson

1
Bir etkinliğin "özel" bir delege olduğunu söyleyebilir miyiz?
Pap

Delege 'bir şey olduğunda birini uyarmak' için bir temsilci kullanabilirsiniz. Belki bunu yapmazsınız, ancak bunu yapabilirsiniz ve bu nedenle olayın doğasında var olan bir özellik değildir.
steve

@Jorge Córdoba delege örneği ve etkinlik delegesi bir gazete sahibi ve etkinliklerdir (Abone Ol veya Aboneliği İptal Et) ve bazı insanlar gazeteyi satın alır ve bazı insanlar gazeteyi satın almaz, gazete sahibi her kişiye gazeteyi satın almaya zorlayamayacağı anlamına gelir doğru ya da yanlış?
Rahul_Patil

37

İşte başvurmak için iyi bir bağlantı. http://csharpindepth.com/Articles/Chapter2/Events.aspx

Kısaca, makaleden alınması - Olaylar delegeler üzerinde kapsüllenir.

Makaleden alıntı:

Olayların C # /. NET'te bir kavram olarak var olmadığını varsayalım. Başka bir sınıf bir etkinliğe nasıl abone olur? Üç seçenek:

  1. Genel delege değişkeni

  2. Bir özellik tarafından desteklenen bir temsilci değişken

  3. AddXXXHandler ve RemoveXXXHandler yöntemlerine sahip bir temsilci değişken

Seçenek 1 açıkça korkunçtur, tüm normal nedenlerle genel değişkenlerden nefret ediyoruz.

Seçenek 2 biraz daha iyidir, ancak abonelerin birbirlerini etkili bir şekilde geçersiz kılmalarına izin verir - someInstance.MyEvent = eventHandler; yeni bir olay eklemek yerine mevcut olay işleyicilerinin yerini alacaktır. Ayrıca, hala özellikleri yazmanız gerekir.

Seçenek 3 temelde olayların size verdiği şeydir, ancak garantili bir kural (derleyici tarafından oluşturulur ve IL'de ekstra bayraklarla desteklenir) ve alan benzeri olayların size verdiği anlamlardan memnunsanız "ücretsiz" bir uygulama ile. Olaylara abone olma ve olaylardan aboneliği iptal etme, olay işleyicileri listesine rasgele erişime izin verilmeden kapsüllenir ve diller, hem bildirim hem de abonelik için sözdizimi sağlayarak işleri basitleştirebilir.


Güzel ve özlü bir açıklama. Thanx
Pap

Bu, her şeyden çok teorik bir kaygıdır, ancak FWIW Her zaman "Seçenek 1 kötü çünkü ortak değişkenlerden hoşlanmıyoruz" argümanı biraz daha fazla açıklama kullanabilir gibi hissettim. "Kötü OOP uygulaması" olduğu için, teknik olarak bir public Delegatedeğişken "veri" yi açığa çıkaracağını söylüyorsa, ancak bilgim dahilinde OOP hiçbir zaman Delegatebir "nesne" veya "mesaj" gibi kavramlardan hiç bahsetmedi. ve .NET zaten veri gibi delegelere zar zor davranıyor.
jrh

Daha pratik önerilerde bulunmak istiyorum, ancak tek bir işleyici olduğundan emin olmak istediğiniz bir durumdaysanız, değişkenlerle kendi AddXXXHandleryöntemlerinizi yapmak private Delegateiyi bir seçenek olabilir. Bu durumda, bir işleyicinin önceden ayarlanmış olup olmadığını kontrol edebilir ve uygun şekilde tepki verebilirsiniz. DelegateTüm işleyicileri temizleyebilmek için nesneyi tutan nesneye ihtiyacınız varsa bu da iyi bir kurulum olabilir ( eventbunu yapmak için herhangi bir yol vermez).
jrh

7

NOT: C # 5.0 Unleashed'e erişiminiz varsa , ikisi arasındaki farkları daha iyi anlamak için Bölüm 18'deki "Olaylar" başlıklı "Delegelerin Düz Kullanımına İlişkin Sınırlamalar" bölümünü okuyun.


Her zaman basit, somut bir örnek almamda bana yardımcı olur. İşte topluluk için bir tane. Öncelikle, Etkinliklerin bizim için yaptıklarını yapmak için delegeleri nasıl kullanabileceğinizi göstereceğim. Sonra aynı çözümün bir örneğiyle nasıl çalışacağını göstereceğim EventHandler. Ve sonra ilk örnekte açıkladıklarımı neden yapmak istemediğimizi açıklıyorum. Bu yazı John Skeet'in bir makalesinden esinlenmiştir .

Örnek 1: Genel temsilci kullanma

Tek bir açılır kutu içeren bir WinForms uygulamam olduğunu varsayalım. Açılır menü bir List<Person>. Kişi Id, Name, NickName, HairColor özelliklerine sahiptir. Ana formda, o kişinin özelliklerini gösteren özel bir kullanıcı kontrolü bulunur. Birisi, seçilen kişinin özelliklerini göstermek için kullanıcı kontrol güncellemesindeki etiketleri açılır listeden bir kişi seçtiğinde.

resim açıklamasını buraya girin

İşte böyle çalışır. Bunu bir araya getirmemize yardımcı olan üç dosyamız var:

  • Mediator.cs - statik sınıf delegeleri tutar
  • Form1.cs - ana form
  • DetailView.cs - kullanıcı kontrolü tüm ayrıntıları gösterir

Sınıfların her biri için ilgili kod:

class Mediator
{
    public delegate void PersonChangedDelegate(Person p); //delegate type definition
    public static PersonChangedDelegate PersonChangedDel; //delegate instance. Detail view will "subscribe" to this.
    public static void OnPersonChanged(Person p) //Form1 will call this when the drop-down changes.
    {
        if (PersonChangedDel != null)
        {
            PersonChangedDel(p);
        }
    }
}

İşte kullanıcı kontrolümüz:

public partial class DetailView : UserControl
{
    public DetailView()
    {
        InitializeComponent();
        Mediator.PersonChangedDel += DetailView_PersonChanged;
    }

    void DetailView_PersonChanged(Person p)
    {
        BindData(p);
    }

    public void BindData(Person p)
    {
        lblPersonHairColor.Text = p.HairColor;
        lblPersonId.Text = p.IdPerson.ToString();
        lblPersonName.Text = p.Name;
        lblPersonNickName.Text = p.NickName;

    }
}

Son olarak Form1.cs dosyamızda aşağıdaki kod bulunmaktadır. Burada, temsilciye abone olan herhangi bir kodu çağıran OnPersonChanged'i çağırıyoruz.

private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
    Mediator.OnPersonChanged((Person)comboBox1.SelectedItem); //Call the mediator's OnPersonChanged method. This will in turn call all the methods assigned (i.e. subscribed to) to the delegate -- in this case `DetailView_PersonChanged`.
}

Tamam. Yani olayları ve sadece delegeleri kullanmadan bu şekilde çalışacaksınız . Bir sınıfa sadece bir delege koyarız - bunu statik veya tek birton ya da her neyse yapabilirsiniz. Harika.

AMA, AMA, AMA, yukarıda açıkladığım şeyi yapmak istemiyoruz. Çünkü kamusal alanlar birçok nedenden dolayı kötüdür . Peki seçeneklerimiz neler? John Skeet'in açıkladığı gibi, seçeneklerimiz şunlardır:

  1. Genel delege değişkeni (yukarıda yaptığımız şey budur. Bunu yapma. Size neden bunun kötü olduğunu söyledim)
  2. Temsilciyi get / set içeren bir mülke yerleştirin (burada sorun abonelerin birbirini geçersiz kılabilmesidir - böylece delege için bir grup yöntemi abone olabiliriz ve sonra yanlışlıkla PersonChangedDel = nulldiğer tüm abonelikleri silerek söyleyebiliriz . burada kalan diğer bir sorun da kullanıcılar delege erişimine sahip oldukları için çağırma listesindeki hedefleri çağırabiliyorlar - harici kullanıcıların olaylarımızı ne zaman yükselteceklerine erişmelerini istemiyoruz.
  3. AddXXXHandler ve RemoveXXXHandler yöntemlerine sahip bir temsilci değişken

Bu üçüncü seçenek aslında bir etkinliğin bize verdiği şeydir. Bir EventHandler bildirdiğimizde, bize bir mülk olarak değil, herkese açık olarak değil, bir delege erişimi sağlıyor, ancak bu şey olarak, yalnızca erişimcileri ekleyen / kaldıran bir etkinlik diyoruz.

Aynı programın nasıl göründüğüne bakalım, ancak şimdi kamu delegesi yerine bir Etkinlik kullanıyor (Arabulucumuzu bir singleton olarak da değiştirdim):

Örnek 2: Herkese açık bir temsilci yerine EventHandler ile

arabulucu:

class Mediator
{

    private static readonly Mediator _Instance = new Mediator();

    private Mediator() { }

    public static Mediator GetInstance()
    {
        return _Instance;
    }

    public event EventHandler<PersonChangedEventArgs> PersonChanged; //this is just a property we expose to add items to the delegate.

    public void OnPersonChanged(object sender, Person p)
    {
        var personChangedDelegate = PersonChanged as EventHandler<PersonChangedEventArgs>;
        if (personChangedDelegate != null)
        {
            personChangedDelegate(sender, new PersonChangedEventArgs() { Person = p });
        }
    }
}

EventHandler'da F12 yaparsanız, tanımın yalnızca ekstra "gönderen" nesnesine sahip genel bir ified delegesi olduğunu gösterecektir:

public delegate void EventHandler<TEventArgs>(object sender, TEventArgs e);

Kullanıcı Kontrolü:

public partial class DetailView : UserControl
{
    public DetailView()
    {
        InitializeComponent();
        Mediator.GetInstance().PersonChanged += DetailView_PersonChanged;
    }

    void DetailView_PersonChanged(object sender, PersonChangedEventArgs e)
    {
        BindData(e.Person);
    }

    public void BindData(Person p)
    {
        lblPersonHairColor.Text = p.HairColor;
        lblPersonId.Text = p.IdPerson.ToString();
        lblPersonName.Text = p.Name;
        lblPersonNickName.Text = p.NickName;

    }
}

Son olarak, Form1.cs kodu şöyledir:

private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
        Mediator.GetInstance().OnPersonChanged(this, (Person)comboBox1.SelectedItem);
}

EventHandler istiyor ve EventArgs bir parametre olarak, bu sınıf içinde sadece tek bir özellik ile oluşturdum:

class PersonChangedEventArgs
{
    public Person Person { get; set; }
}

Umarım bu size neden olaylarımız olduğunu ve delegelerle nasıl farklı olduklarını - ancak işlevsel olarak aynı olduklarını - gösterir.


Bu yazıdaki tüm iyi çalışmaları takdir ettim ve çoğu okumayı sevdim, yine de bir sorunun ele alınmadığını hissediyorum The other problem that remains here is that since the users have access to the delegate, they can invoke the targets in the invocation list -- we don't want external users having access to when to raise our events. Öğesinin en son sürümünde , singleton'a bir başvurunuz olduğunda Mediatoraramaya devam edebilirsiniz OnPersonChange. Belki de Mediatoryaklaşımın bu belirli davranışı engellemediğini ve bir olay veriyoluna daha yakın olduğunu belirtmelisiniz.
Ivaylo Slavov

6

Ayrıca olayları temsilciler için değil, arayüz bildirimlerinde kullanabilirsiniz.


2
@surfen Arabirimi etkinlikler içerebilir, ancak delegeler içeremez.
Alexandr Nikitin

1
Tam olarak ne demek istiyorsun? Action a { get; set; }Bir arayüz tanımına sahip olabilirsiniz .
Chiel ten Brinke

6

Etkinlikler ve delegeler arasında ne büyük bir yanlış anlama !!! Bir temsilci bir TYPE (a classveya bir interfacedoes gibi) belirtirken , bir olay yalnızca bir tür ÜYE'dir (alanlar, özellikler vb.). Ve diğer herhangi bir üye gibi, bir etkinliğin de bir türü vardır. Ancak, bir olay olması durumunda, olayın türü bir temsilci tarafından belirtilmelidir. Örneğin, bir arabirim tarafından tanımlanan türde bir olay bildiremezsiniz.

Sonuç olarak, aşağıdaki Gözlemi yapabiliriz: bir olayın türü bir delege tarafından tanımlanmalıdır ZORUNLU . Bu, olay ve bir temsilci arasındaki temel ilişki ve bölümünde anlatılan II.18 tanımlama olaylar arasında , ECMA-335 (CLI) bölme I VI :

Tipik kullanımda, TypeSpec (varsa) imzası olayın fire yöntemine iletilen bağımsız değişkenlerle eşleşen bir temsilci tanımlar .

Ancak bu gerçek, bir olayın destek delege alanı kullandığını ima ETMEZ . Gerçekte, bir olay seçtiğiniz herhangi bir farklı veri yapısı tipinde bir destek alanı kullanabilir. Bir olayı C # 'da açıkça uygularsanız, olay işleyicilerini saklama biçiminizi seçebilirsiniz ( olay işleyicilerin , olay türünün örnekleri olduğunu unutmayın; bu da zorunlu olarak bir delege türüdür ; önceki Gözlemden) ). Ancak, bu olay işleyicilerini (delege örnekleri olan) a Listveya a Dictionaryveya başka herhangi bir veri yapısında veya hatta destek delege alanında saklayabilirsiniz . Ancak bir delege alanı kullanmanın zorunlu OLMADIĞINI unutmayın.


4

.Net dosyasındaki bir olay, her ikisi de belirli türde bir temsilci bekleyen bir Add yöntemi ile Remove yönteminin belirlenmiş bir birleşimidir. Hem C # hem de vb.net, olay aboneliklerini tutmak için bir temsilci tanımlayacak ve bu abonelik temsilcisine gönderilen / gönderilen temsilci ekleyecek / kaldıracak ekleme ve kaldırma yöntemleri için kod otomatik olarak oluşturabilir. VB.net ayrıca, yalnızca boş değilse abonelik listesini çağırmak için kodu otomatik olarak oluşturur (RaiseEvent deyimi ile); bazı nedenlerden dolayı, C # ikincisini üretmez.

Çok noktaya yayın delegesi kullanarak olay aboneliklerini yönetmek yaygın olsa da, bunu yapmanın tek yolu olmadığını unutmayın. Kamusal bir bakış açısıyla, bir olay abonesi bir nesneye olayları almak istediğini nasıl bildireceğini bilmelidir, ancak yayıncının olayları yükseltmek için hangi mekanizmayı kullanacağını bilmesine gerek yoktur. Ayrıca, .net'teki olay verisi yapısını kim tanımlasa da, onları yükseltmenin genel bir yolu olması gerektiğini düşünürken, ne C # ne de vb.net bu özelliği kullanmaz.


3

Etkinlik hakkında basit bir şekilde tanımlamak için:

Etkinlik, iki kısıtlamaya sahip bir temsilciye REFERANS

  1. Doğrudan çağrılamaz
  2. Doğrudan değerler atanamaz (örn. EventObj = delegateMethod)

İkisinin üstünde delegeler için zayıf noktalar var ve etkinlikte ele alındı. Kemancıdaki farkı göstermek için tam kod örneği burada https://dotnetfiddle.net/5iR3fB .

Olayı ve Temsilciyi ve farkı anlamak için temsilciye değer atanan / atayan istemci kodu arasında açıklamayı değiştirin

İşte satır içi kod.

 /*
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();
    }


}

2

Temsilci, tür güvenli bir işlev işaretçisidir. Etkinlik, temsilci kullanan yayıncı-abone tasarım modelinin bir uygulamasıdır.


0

Ara Dil'i işaretlerseniz, .net derleyicisinin delegate'i, invoke, beginInvoke, endInvoke ve delegate sınıfı gibi başka bir sınıftan miras alınan "BuildMulticast" gibi bazı yerleşik işlevlerle IL'de kapalı bir sınıfa dönüştürdüğünü bileceksiniz. Event, bazı ek özelliklere sahip bir Delege alt sınıfıdır.

Olay örneği ile temsilci arasındaki fark, olayı bildirimin dışında çalıştıramazsınız. A sınıfında bir olay bildirirseniz, bu olayı yalnızca A sınıfında çalıştırabilirsiniz. A Sınıfında bir temsilci bildirirseniz, bu temsilciyi her yerde kullanabilirsiniz. Bence bu aralarındaki temel fark

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.