Delegatorlar və hadisələr arasındakı fərqlər hansılardır?

Delegatorlar və hadisələr arasındakı fərq nədir? İcra edilə bilən funksiyalara istinad etməyin?

278
27 авг. Sean Chambers tərəfindən təyin olunan 27 Avqust. 2008-08-27 02:06 '08 at 2:06 am 2008-08-27 02:06
@ 11 cavab

Hadisə bəyannaməsi nümayəndə heyətinə bir soyuducu və qoruma qatqısı əlavə edir. Bu qorunma, nümayəndəli müştərilərin nümayəndəni və zəng siyahısını sıfırlamasını maneə törədir və zəng siyahısından hədəfləri əlavə etmək və ya silmək üçün imkan verir.

251
27 авг. Cavab mmcdole 27 aug. 2008-08-27 02:16 '08 at 2:16 pm 2008-08-27 02:16

Sintaktik və əməliyyat xüsusiyyətlərinə əlavə olaraq, semantik bir fərq var.

Deleqlər konseptual funksional şablonlardır; yəni funksiyanı bir "tip" nümayəndəsi hesab etmək üçün uyğun olmalıdır ki, bir müqavilə ifadə.

border=0

Hadisələr ... yaxşı, hadisələri təmsil edir. Onlar bir şey baş verdiyi zaman kimsə xəbərdar etmək üçün nəzərdə tutulmuşdur və bəli, bir nümayəndənin tərifinə uyğundur, lakin bu da eyni deyil.

Hətta eyni olduqda (syntactically və IL kodunda) olsa da, bir semantik fərq ola bilərdi. Ümumiyyətlə, mən eyni şəkildə həyata keçirildikdə belə iki fərqli anlayışa görə iki fərqli adın olmasını üstün tuturam (bu, mən eyni kodu iki dəfə istəyirəm) deməkdir.

91
27 авг. Jorge Córdoba tərəfindən verilmiş cavabı 27 Avqust. 2008-08-27 02:39 '08 at 2:39 am 2008-08-27 02:39

Fərqləri anlamaq üçün bu 2 nümunəyə baxa bilərsiniz.

Delegatorlar ilə nümunə (bu halda, Fəaliyyət, bir dəyər verməyən bir növ nümayəndəsidir)

 public class Animal { public Action Run {get; set;} public void RaiseEvent() { if (Run != null) { Run(); } } } 

Bir nümayəndədən istifadə etmək üçün belə bir şey etməlisiniz:

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

Bu kod yaxşı işləyir, ancaq zəif nöqtələrə sahib ola bilərsiniz.

Məsələn, yazsam:

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

sonuncu kod xətti ilə, əvvəlki hərəkətləri yalnız bir eksik ilə yenidən təyin edim ( + istifadə etdiyim += )

Digər bir zəif nöqtəsidir ki, Animal sinifini istifadə edən hər bir RaiseEvent sadəcə animal.RaiseEvent() çağıraraq RaiseEvent qaldıra bilər.

Bu zəif nöqtələrin qarşısını almaq üçün, C #-də events istifadə edə bilərsiniz.

Heyvan sinifiniz aşağıdakı kimi dəyişəcək:

 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")); } } 

hadisələri tetiklemek

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

Fərqlər:

  • Bir ictimai əmlakı istifadə etmirsiniz, ancaq bir ictimai sahə (hadisələri istifadə edərək, derleyici sahələrinizi istenmeyen girişdən qoruyur).
  • Hadisələr birbaşa təyin edilə bilməz. Bu vəziyyətdə, davranışın yenidən təyin olunması ilə göstərdiyim əvvəlki səhvlərə səbəb olmaz.
  • Sınıfınızın heç biri bu hadisəni qaldıra bilməz.
  • Hadisələr interfeys bildirişinə daxil edilə bilər, sahə isə mümkün deyil

Qeydlər:

EventHandler aşağıdakı nümayəndə tərəfindən elan edilir:

 public delegate void EventHandler (object sender, EventArgs e) 

tələb olunan göndərici (obyekt növü) və hadisə arqumentləri. Statik metodlara əsasən göndərən null olur.

EventHandler<ArgsSpecial> istifadə edən bu nümunə də EventHandler istifadə edilə bilər.

EventHandler haqqında sənədlər üçün əlaqə saxlayın

83
12 июля '14 в 14:11 2014-07-12 14:11 cavab 12 iyul, 14:14 saat 14: 37 -da təqdim olunacaq 2014-07-12 14:11

Link üçün daha yaxşı bir link. http://csharpindepth.com/Articles/Chapter2/Events.aspx

Qısacası, məqalənin alınması - Tədbirlər nümayəndə heyətləri üzərində bir encapsulation.

Məqalədən sitat:

C # /. NET hadisələrində konsepsiya kimi mövcud deyildik. Başqa bir sinif bir hadisəyə necə qoşulurdu? Üç variant:

  1. İctimaiyyət nümayəndəsi dəyişir

  2. Mülkiyyət tərəfindən dəstəklənən nümayəndəlik dəyişən

  3. AddXXXHandler və RemoveXXXHandler metodları ilə dəyişdirin

Variant 1, ictimai dəyişənlərdən nifrət etdiyimiz bütün səbəblərə görə açıq-aşkar qorxunc.

Variant 2 bir az daha yaxşıdır, ancaq abunəçilər bir-birini səmərəli şəkildə üstələyməyə imkan verir - someInstance.MyEvent = eventHandler yazmaq çox asan olardı; yeni bir əlavə etmək əvəzinə hər hansı bir hadisə işleyicisini əvəz edəcək. Bundan əlavə, hələ də xüsusiyyətləri yazmaq lazımdır.

Variant 3 əsasən nə hadisələr verir, ancaq birbaşa sahə hadisələrini verən semantiklərdən razısınızsa, zəmanətli bir müqavilə ilə (kompilyator tərəfindən yaradılan və IL-də əlavə bayraqlarla dəstəklənən) və "azad" həyata keçirilir. Hadisələrə abunə olmaq və onlara abunəliklər hadisə işləyicilərinin siyahısını təsadüfən təmin etmədən encapsüllənir və dil həm elan, həm də abunə üçün sintaksis təmin edərək tapşırıqları sadələşdirə bilər.

34
12 апр. cavab 12 aprel tarixində titreme tərəfindən verilir 2013-04-12 12:45 '13 saat 12:45 'də 2013-14-12 12:45' də

Hadisələr və nümayəndələr arasında nə qədər böyük bir anlaşılmazlıq var! Tədbir bir üzv növüdür (məsələn, sahələr, xüsusiyyətlər, və s.), Bir nümayəndə isə bir TYPE (məsələn, class və ya interface ) müəyyənləşdirir. Və hər hansı digər üzv kimi, hadisə bir növüdür. Ancaq bir hadisə halında hadisənin növü nümayəndə tərəfindən təyin edilməlidir. Məsələn, interfeyslə müəyyənləşdirilmiş bir növ hadisəni bəyan edə bilməzsiniz.

Nəhayət, aşağıdakı müşahidə edə bilərik : hadisənin növü nümayəndə təyin olunmalıdır . Bu, hadisə ilə nümayəndə arasında əsas əlaqədir və II.18 bölməsində təsvir edilmişdir. ECMA-335 Hadisələrinin (CLI) təsviri I-VI bölmələri :

Tipik istifadə ilə TipSpec (əgər varsa) imzası hadisənin yanğın üsuluna ötürülmüş dəlilləri eşleştiren delegeyi müəyyən edir .

Bununla belə, bu fakt hadisənin nümayəndəliyin dəstək sahəsini istifadə etməsi demək deyildir . Həqiqətən, bir hadisə seçdiyiniz hər hansı digər məlumat strukturunun dəstək sahəsini istifadə edə bilər. C #-də bir hadisəni dəqiq həyata keçirirsinizsə, hadisə işleyicilerinin necə saxlanacağını seçə bilərsiniz. (qeyd etmək lazımdır ki, hadisə işləyiciləri hadisənin növündəki nümunələrdir və bu, öz növbəsində, əvvəlki Müşahidədən --- məcburi bir nümayəndənin olmasıdır ). Ancaq, bu həddi işləyicilərini (nümayəndənin nümunələri olan) bir List və ya Dictionary kimi bir məlumat strukturunda və ya həvalə edilmiş dəstək sahəsində hətta saxlaya bilərsiniz. Lakin nümayəndə heyətindən istifadə etmək lazım deyil.

6
18 февр. 18 Fevralda Miguel Gamboaya cavab verin 2015-02-18 13:58 '15 at 13:58 2015-02-18 13:58

Həm də hadisələrin istifadəçilər tərəfindən deyil, interfeys bildirişlərində istifadə edə bilərsiniz.

6
25 авг. Paul Hill tərəfindən verilən cavabı 25 Av. 2010-08-25 17:37 '10 'da 17:37' da 2010-08-25 17:37 'də

Qeyd. C # 5.0-un Unleashed- ə daxil olmağınız varsa, Fəsil 18-də "Tədbirlər" başlığı altında "Aralarındaki fərqləri daha yaxşı başa düşmək üçün" nümayəndələri normal istifadə üzrə məhdudiyyətlər "oxuyun.


Həmişə mənə sadə və konkret bir nümunə yaratmağa kömək edir. Beləliklə, burada icma üçün. Birincisi, biz yalnız nə üçün etdiyimizi etmək üçün nümayəndələri istifadə edə biləcəyinizi göstərəcəyəm. Sonra eyni həllin EventHandler bir nümunəsi ilə necə çalışacağını göstərəcəyəm. Və sonra ilk nümunədə izah etdiyim işləri etmək istəmədiyimiz səbəbini izah edəcəyəm. Bu yazı John Skit tərəfindən yazılmışdır .

Misal 1: İctimaiyyət nümayəndəsini istifadə etmək

Bir açılan siyahı ilə bir WinForms proqramı olduğumu varsayalım. Drop-down obyekti List<Person> bağlıdır. Şəxsin Id, Ad, İstifadəçi adı, Saç Rəngi ​​xüsusiyyətləri olduğu yer. Əsas form bu şəxsin xüsusiyyətlərini göstərən xüsusi nəzarətdən istifadə edir. Kimsə, seçilmiş şəxsin xüsusiyyətlərini göstərmək üçün istifadəçi idarəetmə yeniləməsində olan etiketlərin açılır siyahısında bir adam seçir.

2019

6
13 апр. Trevor 13 apreldə cavab verdi 2015-04-13 01:22 '15 at 1:22 'də 2015-04-13 01:22

.Net-də bir hadisə, Əlavə üsulunu və Silinmə metodunun təyin olunmuş birləşməsidir, həm də həmin bir xüsusi nümayəndə tipini gözləyir. Həm C # və vb.net həm də bu nümayəndə heyətinə / nümayəndələrə göndərilən hadisə abunəliyini saxlamaq və əlavə etmək / silmək üçün nümayəndələri müəyyən edəcək metodları əlavə etmək və silmək üçün avtomatik olaraq kodu yarada bilər. VB.net ayrıca abunə siyahısına zəng etmək üçün avtomatik olaraq bir kod (RaiseEvent ifadəsi ilə) yaradır və yalnız boş deyilsə; Nədənsə, C # sonuncu yaradır.

Tədbir abunəliklərini idarə etmək üçün bir multicast delegatının istifadə olunmasına baxmayaraq, bunu etmək üçün təkcə vasitə deyildir. İctimaiyyət baxımından potensial bir hadisə abunəçi bir obyektin hadisələr almaq istədiyini bilməsi üçün necə məlumat verməlidir, ancaq hadisənin artırılması üçün naşirin hansı mexanizmdən istifadə edəcəyini bilməməsi lazımdır. Qeyd edək ki, .net saytında hadisələrin məlumat strukturunu müəyyən edən bir kəs, onları artırmaq üçün ictimaiyyətə çatdırılmalı yol olduğunu düşünməsinə baxmayaraq, bu funksiyanı nə C #, nə də vb.net istifadə edir.

4
27 авг. cavab supercat 27 aug verilir . 2011-08-27 20:07 '11 saat 20:07 'da 2011-08-27 20:07

Təsadüfi bir hadisə təsvir etmək üçün:

İki məhdudiyyətlə bir nümayəndə üçün REFERENCE hadisə

  • Birbaşa zəng edə bilmir
  • Birbaşa dəyərləri təyin edə bilməzsiniz (məsələn, eventObj = delegateMethod)

Yuxarıdakılar nümayəndələri üçün zəif nöqtələrdir və işdə baxılır. Fiddlerdeki fərqləri göstərmək üçün tam kod nümunəsi burada yerləşir https://dotnetfiddle.net/5iR3fB .

Tədbir və Deleqata və fərqi anlamaq üçün nümayəndələri dəyərləri təyin edən / verən müştəri kodu arasında keçid edin.

Daxili kod burada.

   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 (eg 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(); } } 
3
13 сент. Venkatesh Muniyandi tərəfindən verilib cavab Sep 13 2016-09-13 03:09 '16 at 3:09 2016-09-13 03:09

Bir nümayəndə bir təhlükəsiz funksiya göstərici növüdür. Bir hadisə, bir nümayəndənin istifadə etdiyi bir naşir-abunəçi dizayn nümunəsinin tətbiqidir.

0
14 янв. Cavab 14 yanvar tarixində Weidong Shen tərəfindən verilir . 2019-01-14 02:58 '19, 2:58, 2019-01-14 02:58

ContravarianceContravariance nümayəndəlik obyektləri üçün əlavə rahatlıq təmin edir. Digər tərəfdən, hadisə belə bir anlayışa malik deyildir.

  • Covariance metodun qaytarılması növü nümayəndəin geri qaytarılma növünü göstərən bir sinifdən əldə edilən bir sinif olduğu bir nümayəndə təyin etmək üçün bir üsul təyin etməyə imkan verir.
  • Contravariance , parametr parametrinin növü, nümayəndə parametri olaraq göstərilən sinifin əsas sinifi olduğu bir Contravariance bir metodu təyin etməyə imkan verir.
0
29 авг. Cavab vivek nuna 29 avqustda verilir . 2018-08-29 09:35 '18 'də 9:35' də 2018-08-29 09:35 'da

dair digər suallar və ya soruşun