安徽新华电脑专修学院_安徽电脑培训_安徽电脑培训学校_合肥电脑培训

當(dāng)前位置:首頁 > 網(wǎng)站舊欄目 > 學(xué)習(xí)園地 > 程序開發(fā)教程 > 我對.NET中delegate和event區(qū)別的理解

我對.NET中delegate和event區(qū)別的理解
2009-12-23 10:53:14  作者:cnblogs  來源:cnblogs

       前幾天和朋友老鄧討論delegateevent區(qū)別的時(shí)候,老鄧問我對他們的理解,當(dāng)時(shí)自己沒理解清楚,只是很簡單的一句話:event就是特殊的delegate,也即eventdelegate的子集。并且我對老鄧解釋只要你愿意并完全信任調(diào)用自己代碼的client,你完全可以將所有的事件用delegate代替。

       后面自己仔細(xì)思考了一下,發(fā)現(xiàn)自己理解的局限性,確實(shí)delegateevent有很多的相似之處,并且delegate完全能實(shí)現(xiàn)event的功能。但我并未認(rèn)證考慮為什么微軟要設(shè)計(jì)這樣一個(gè)限制了delegate功能的東西出來,也沒從觀察者角度理解events。相對delegate來說,客戶端即觀察者只能調(diào)用+=或者-+來添加自己對相應(yīng)事件觸發(fā)的通知,它不能調(diào)用new來實(shí)例化發(fā)布者的event事件如單擊事件,或者直接將發(fā)布者的event對象直接賦值null從而撤銷發(fā)布者所有通知列表,也不能通過調(diào)用諸如this.btn.clck(obj,e)之類的方式來觸發(fā)event發(fā)布事件通知。當(dāng)我們理解了觀察者模式并完全站在實(shí)際對象角度考慮相信就不難理解為什么event會比delegate多這么多限制了,很顯然,第一,觀察者不能也不應(yīng)該有權(quán)限實(shí)例化事件發(fā)布者的消息列表,同理,觀察者不應(yīng)該能控制事件發(fā)布者對事件的通知,這些所有的操作應(yīng)該都是發(fā)布者內(nèi)部的事件而不能交由外部對象來控制,因此,才產(chǎn)生了event對象,它是通過對delegate的限制來封裝一部分本來就不應(yīng)該暴露在外的行為,從而更符合面向?qū)ο蟮乃季S。我想,在發(fā)布者內(nèi)部的click應(yīng)該還是一個(gè)委托,不過在添加了event關(guān)鍵字之后,.net會通過一系列方法將這個(gè)delegate包裹起來從而封裝了一部分本來就不應(yīng)該暴露的行為。這樣更符合面向?qū)ο蟮淖龇ā?/span>

      因此我認(rèn)為event在本質(zhì)上所做的工作應(yīng)該還是通過delegate來實(shí)現(xiàn)的,或者至少原理相同,event關(guān)鍵字只不過是clr給我們對所定義的delegate對象的一個(gè)封裝,這樣對象可以不必暴露本來就不應(yīng)該被外部對象看到的方法,如果愿意的話,我們完全可以自己去做這些封裝的工作。他們最終都是使得我們所定義的對象更加符合封裝的原則。

   現(xiàn)在我們可以用代碼驗(yàn)證這個(gè)猜想是否正確,首先看一段代碼:

委托事件示例代碼
    public delegate void TestDelegate();
    
class Program
    {
        
public static TestDelegate myDelegate;//普通的委托聲明
        public static event TestDelegate myEvent;//事件聲明
        static void Main(string[] args)
        {
            myDelegate 
+= TestEvent;
            myEvent 
+= TestEvent;
            myDelegate();
            myEvent();
        }
        
static void TestEvent()
        {
            Console.WriteLine(
"Hello Event");
        }
    }

   代碼中事件除了多了個(gè)關(guān)鍵字聲明之外與普通委托并無不同,那么在Reflector中它們有何不同呢?

委托事件IL代碼
.class private auto ansi beforefieldinit Program
    extends [mscorlib]System.Object
{
    .
event ConsoleApplication1.TestDelegate myEvent
    {
        .addon 
void ConsoleApplication1.Program::add_myEvent(class ConsoleApplication1.TestDelegate)
        .removeon 
void ConsoleApplication1.Program::remove_myEvent(class ConsoleApplication1.TestDelegate)
    }
    .method 
public hidebysig specialname rtspecialname instance void .ctor() cil managed
    {
    }
    .method 
private hidebysig static void Main(string[] args) cil managed
    {
        .entrypoint
    }
    .method 
private hidebysig static void TestEvent() cil managed
    {
    }
    .field 
public static class ConsoleApplication1.TestDelegate myDelegate

    .field 
private static class ConsoleApplication1.TestDelegate myEvent
}

   這里我們可以看到在IL中它會首先聲明一個(gè)同名普通私有字段,注意這里該字段被聲明成私有的,這是為了防止外部對象非法訪問這個(gè)委托,然后再看上面的event會有兩個(gè)操作:

代碼
.event ConsoleApplication1.TestDelegate myEvent
    {
        .addon 
void ConsoleApplication1.Program::add_myEvent(class ConsoleApplication1.TestDelegate)
        .removeon 
void ConsoleApplication1.Program::remove_myEvent(class ConsoleApplication1.TestDelegate)
    }

  這個(gè)就是event關(guān)鍵字所做的封裝,也就是它允許myEvent委托僅僅暴露add和remove新的委托,而該委托的其他操作都被禁止了。

  上面是我自己做的一些研究,后面我讀到CLR via C#時(shí)候看到對事件類似的描述,在書中第230頁(英文版)中提到, 在我們聲明一個(gè)事件的時(shí)候,其實(shí)編譯器會幫你生成一些代碼,e.g. public event EventHandler<NewMailEventArgs> NewMail;當(dāng)編譯器碰到這段代碼時(shí),它會把它轉(zhuǎn)換成下面的代碼:

代碼
// 1. A PRIVATE delegate field that is initialized to null 
private EventHandler<NewMailEventArgs> NewMail = null
// 2. A PUBLIC add_Xxx method (where xxx is the Event name) 
// Allows objects to register interest in the event. 
[MethodImpl(MethodImplOptions.Synchronized)]
public void add_NewMail(EventHandler<NewMailEventArgs> value) { 
NewMail 
= (EventHandler<NewMailEventArgs>
Delegate.Combine(NewMail, value); 
}
// 3. A PUBLIC remove_Xxx method (where Xxx is the Event name) 
// Allows objects to unregister interest in the event. 
[MethodImpl(MethodImplOptions.Synchronized)]
public void remove_NewMail(EventHandler<NewMailEventArgs> value) { 
NewMail 
= (EventHandler<NewMailEventArgs>
Delegate.Remove(NewMail, value); 
}

   這段代碼跟我在Reflector中看到的IL類似。這里正是event對delegate所做的封裝了。

   最后謝謝文楚,由于很少分享自己所得,很多東西我并未深入研究,僅僅停留在猜想階段就不了了。希望后面補(bǔ)充的東西能對別人有所幫助吧!


安徽新華電腦學(xué)校專業(yè)職業(yè)規(guī)劃師為你提供更多幫助【在線咨詢
主站蜘蛛池模板: 山东万通液压股份有限公司-自卸车专用油缸,能源采掘设备油缸,机械装备用油缸,油气弹簧,工程机械油缸,液压元件 | 整体滤板模板-S型塑料滤砖-MBBR生物悬浮球填料-微孔曝气器-大恒环保科技 | 滑动轴承_无油自润滑轴承_复合干式_含油铜套_石墨铜套-嘉善盛元自润滑轴承厂 | 铝合金锻造|链轮曲柄-同力铝业股份有限公司 | 松下PLC经销商-松下传感器-放大器-电磁阀-光电开关-金器[东莞均钛]品牌气动元件及工控产品一站式供应商 | 台车炉厂家_台车式退火炉_台车式回火炉—安徽大新工业炉有限公司 | 住友套管总代理-日本住友套管-住友热缩管-上海弘奇电子科技有限公司 | 温湿度变送器_pm2.5传感器_湿敏电阻_二氧化碳传感器_甲醛传感器-美特瑞科技 | 水平转头微孔板离心机-米欧微孔板离心机-北京乾明基因技术 | 陕西筱润智能科技有限公司 干部人事智能档案柜 智能密集架 智能档案柜 部队选层文件智能柜 智能枪弹柜 财务智能档案柜 边防武警智能密集架 医院智能档案柜 部队选层文件智能柜智能枪弹柜 学校医院文件柜 企事业单位公检法智能文件柜 生产厂家-筱润智能科技有限公司 RFID射频智能密集架 全自动智能选层档案柜 智能密保柜 枪柜部队营房营具床桌椅办公家具 办公用品档案盒设备货架 全自动智能选层柜生产厂家-筱润智能科技有限公司 | 新能源洗扫车、新能源压缩垃圾车_新能源路面养护车_电动树叶收集车_电动扫地机_电动洗地机_高尔夫球车 | 生物安全柜检测,GMP设备确认,仪器性能确认,洁净厂房检测,仓储温湿度检测-上海熙迈 | 专注客流统计,客流分析,人流统计系统,客流计数器-广州市天威电子科技有限公司 | 每天一篇励志文章,每晚一个励志故事—励志人生网 | 西安logo设计公司/西安包装设计公司/西安画册设计公司/西安广告公司/西安品牌设计公司/泰勒广告 雾度计-雾度仪-透光率测试仪-3nh品牌雾度仪生产厂家 | 箱式电炉,箱式烧结炉,箱式马弗炉,箱式实验炉,高温箱式电阻炉,箱式加热炉,箱式退火炉,箱式真空气氛炉洛阳研博炉业有限公司 | 塑木地板-木塑地板厂家「云南昆明楚雄曲靖玉溪塑木地板」云南云冶中信塑木新型材料有限公司 | 艺术网 - 大型艺术类权威门户站 艺考培训-中影人教育 【官网】-中国艺考教育的引航者 | 眉山净源居环保科技有限公司,眉山除甲醛公司,眉山甲醛治理,眉山保洁服务,眉山家政保洁,眉山家电维修 - 眉山净源居环保科技有限公司,眉山除甲醛公司,眉山甲醛治理,眉山保洁服务,眉山家政保洁,眉山家电维修 | 银马全自动免烧砖机设备厂家,提供免烧砖机价格报价及生产视频 | 搅拌设备_搅拌器_浓密机_浆式_顶入式_不锈钢「赛鼎机械」 | 围墙护栏,护栏网,围栏,锌钢栅栏,护栏网厂家--安平县沃达金属丝网制造有限公司 | 猪粪烘干机|小型鸡粪烘干机|猪粪烘干机价格|小型鸡粪烘干机价格 - 河南宏科重工干燥机设备生产厂家 | 市南人才网_市南招聘网_求职找工作平台| 小麦硬度指数仪-石灰活性测定仪-智能型砂强度仪-北京同德创业科技有限公司 | 新中式家具,广东新中式家具,广州新中式家具,佛山新中式家具,顺德新中式家具,乐从新中式家具,新中式家具厂家直销--唐明雅居 | 声测管厂家_声测管现货_桥梁桩基声测管_注浆管_沉降板-沧州市福顺昌钢管有限公司 | 无尘投料站-真空上料机-旋振筛|超声波振动筛|摇摆筛|筛分机-新乡市欧霖佳机械有限公司 | 信管飞软件官网 - 亚拓软件旗下精细化管理软件、进销存管理软件、混凝土ERP、通风设备ERP、风管报价软件、出纳软件、送货单打印软件、ERP软件等免费下载 | 上海机械加工-机械加工-精密机械加工-上海欧野精工机械有限公司 上海慧泰仪器制造有限公司_一体型马弗炉-可控真空干燥箱-强光稳定性试验箱 | 减速电机-调速电机-四大系列减速机-减速电机厂家-深圳市鑫希田机电有限公司官网 | 杀菌剂_除藻剂_杀菌灭藻剂_1227杀菌剂_中北精细化工 | 石笼网|镀锌石笼网|石笼网价格|包胶涂塑石笼网箱-河北海峰石笼网厂 | 聊城市城乡规划设计研究院官方网站 | 视觉检测设备_CCD光学筛选机_分度盘光学筛选机-无锡精质智能装备 | 扬州市德友线缆有限公司-业从事高端特种线缆研发、制造、销售与服务。 | 兰州物流公司_兰州货运公司_兰州物流电话上门取货_兰州立辉物流公司 | 气体泄漏检测仪,COD水质分析仪,RD8200管线探测仪-成都恒通兴业科技有限责任公司 | 湖南净声源环保科技有限公司是一家专业从事噪声治理和建筑声学设计生态环境综合治理服务的企业,专业从事株洲电梯隔音治理,湘潭中央空调降噪处理,衡阳邵阳冷却塔噪音治理,岳阳常德大型风机噪声隔音降噪,张家界空压机噪声治理,益阳配电房变压器噪声治理,专业郴州永州工厂企业车间噪声治理,怀化娄底专业机械设备减振降治理,武汉噪音治理隔音降噪公司,孝感噪音治理,立式球磨机的噪声控制,专业隔音降噪公司,、以及各类机械动力设备减振降噪噪声治理的公司,同时为客户提供咨询与解决方案 | 聚氨酯碰头,聚氨酯托辊,聚氨酯地辊/地滚轮/地轮/托绳轮-济宁卓力聚氨酯制品有限公司 | 人防信号控制箱厂家-液位控制器价格-信号灯箱批发厂家-消声加热器-鼎兴自控 |