青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

隨筆 - 55  文章 - 15  trackbacks - 0
<2012年5月>
293012345
6789101112
13141516171819
20212223242526
272829303112
3456789

常用鏈接

留言簿

隨筆分類

隨筆檔案

搜索

  •  

最新評論

閱讀排行榜

評論排行榜

本文章為farproc.com站長袁曉輝(海洋)的原創文章,作者保留所有權利。如果轉載,請務必注明來自www.farproc.com!!

 

作為一個C++程序員,學習C#應該不是一件很困難的事情,因為C#的許多特性都是從C++“繼承”(不精確的說法)來的。但是C#作為一門全新的編程語言,它必然有自己的新特性,而這些C++中并不存在的新特性正是我們從C++轉向C#的過程中必須認真重新學習的東西。“事件(event)”是C#的一個比較簡單的新特性,我們今天就從“事件”開始,看一看C#的事件到底是怎么回事。

C#的事件和Windows窗口編程中提到的“事件”、“消息”、“事件驅動”等在概念上是很類似的。我們在一個窗口上移動鼠標指針,系統就會產生WM_MOUSEMOVE消息(在vb中就是激發mousemove事件),只要我們告訴系統一個函數指針,系統就會通過這個回調函數通知我們,這是Windows窗口編程中的“事件”。C#中的事件的外延更廣,任何一個對象都可以擁有事件,客戶可以“定制”該對象的事件,當該對象的內部狀態發生特定的改變時,就會通過定制事件時指定的函數代理(delegate)調用這個函數通知客戶。當客戶不在需要事件通知時,可以“撤消”對該事件的定制。

Now is the show time!模仿秀現在開始!

一、C#

我們先來看一個C#中一個“事件”的最簡單例子:

VS.NET中新建一個C#Console Application,項目名稱為“eventtest”。為該項目新加一個類MyClass,對應的源文件為MyClass.cs代碼如下:

using System;

 

namespace eventtest

{

    //定義EventHandler函數代理

    public delegate void EventHandler();

 

    /// <summary>

    ///

    /// </summary>

    public class MyClass

    {

        //構造函數

        public MyClass(){}

        //聲明一個事件

        public event EventHandler AEvent;

        //激發事件

        public void FireEvent()

        {

            if(AEvent != null)

            {

                //直接把event當做函數調用

                AEvent();

            }

        }

    }

}

 

public event EventHandler AEvent;就是給MyClass定義了一個事件(通過event關鍵字),其事件處理函數(通知函數)的原型由EventHandler函數代理(類似C++中的函數指針)指定。

FireEvent()成員函數用于激發該事件,如果客戶定制了該event,當本類對象的FireEvent()公開方法被調用時,客戶應該可以得到通知。在Main函數里寫如下代碼:

using System;

 

namespace eventtest

{

    /// <summary>

    /// Class1 的摘要說明。

    /// </summary>

    class Class1

    {

        /// <summary>

        /// 應用程序的主入口點。

        /// </summary>

        [STAThread]

        static void Main(string[] args)

        {

            MyClass Obj = new MyClass();

            Obj.AEvent += new EventHandler(MyEventHandler);//定制事件

            Obj.FireEvent();//這行將導致MyEventHandler被調用

 

            Obj.AEvent -= new EventHandler(MyEventHandler);//撤消事件

            Obj.FireEvent();//這里將不會引發事件

           

            Console.WriteLine("結束!");

            Console.ReadLine();

        }

       

        //事件處理函數

        public static  void MyEventHandler()

        {

            Console.WriteLine("This is a event!");

        }

    }

   

}

首先寫一個具有適當形式的事件處理(通知)函數 MyEventHandler,然后通過Obj.AEvent += newEventHandler(MyEventHandler)來定制事件。通過“-=”來撤消事件定制。

運行程序我們可以發現,當客戶(Class1)定制了Obj的AEvent事件后,在Obj的FireEvent()成員函數被調用時,客戶可以在MyEventHandler函數中得到通知(在這里只是簡單地輸出一個文本)。而當客戶撤消該事件的定制后,就不會再得到該事件通知。

 

二、C++版

下面我們在C++中模擬該機制:

由于C++不支持event關鍵字,我們就必須自己寫代碼。在這里我通過模板類的手段來實現,因為該手段實現的效果和C#比較類似。

在VC6中新建一個win32 console app,命名為“cppevent“。新建一個.h頭文件,命名為“event.h”,代碼如下:

//event.h

 

template <typename Handler>

class event

{

private:

         Handler m_Handler;

protected:

         //模擬C# event add/remove訪問器

         //如果要重新實現add/remove請在派生類中重寫這兩個函數

         virtual void add(const Handler value){m_Handler = value;};

         virtual void remove(const Handler value){if(value == m_Handler)m_Handler = NULL;};

public:

         //構造函數

         event():m_Handler(NULL){}

         //+= 操作符

         eventoperator += (const Handler value)

         {

                   add(value);

                   return *this;

         }

         //-=操作符

         eventoperator -= (const Handler value)

         {

                   remove(value);

                   return *this;

         }

         //PFN_EVENT_HANDLE 操作符

         operator Handler()

         {

                   return m_Handler;

         }

};

 

為了能夠在定義是指定事件處理函數的原型,我使用了template,為了能和C#一樣用+=-=來定制和撤消事件,我重載了這兩個操作符(C#不支持操作符重載),為了能像C#一樣直接把event當做函數調用,我有重載了Handler自定義轉換操作符,可惜的是,這一點模擬得不是很像,在調用時還必須來一次強制轉換才可以:(,具體參看后面的代碼:

C++版的MyClass如下:

//MyClass.h

#include "event.h"

//定義EventHandler的函數指針類型

typedef void(*EventHandler)();

 

class MyClass

{

public:

         //構造函數

         MyClass(){};

         //聲明一個事件

         event<EventHandlerAEvent;

         //激發事件

         void FireEvent()

         {

                   if(AEvent != NULL)

                   {

                            //C++中必須用EventHandler進行強制類型轉換

                            ((EventHandler)AEvent)();

                   };

         }

 

};

 

C#版的MyClass比較一下你就會發現代碼非常接近,當然,C#是在語言級直接支持event關鍵字的,而C++不支持,用模板類代替,所以聲明事件的代碼有些不一樣。還有就是FireEvent()C++不能把event對象直接當做函數來調用,多了強制類型轉換。

 

C++版的客戶代碼如下:

// cppevent.cpp : Defines the entry point for the console application.

//

 

#include "stdafx.h"

#include "MyClass.h"

//向前聲明

void MyEventHandler();

 

int main(int argccharargv[])

{

         MyClass Obj;

         Obj.AEvent += MyEventHandler;//定制事件

         Obj.FireEvent();//這行將導致MyEventHandler被調用

 

         Obj.AEvent -= MyEventHandler;//撤消事件

         Obj.FireEvent();//這個將不會引發事件

 

 

         printf("結束!/n");

         char n;

         scanf("%c", &n);

         return 0;

}

 

void MyEventHandler()

{

         printf("This is a event!/n");

}

 

我們可以看到,可C#版的客戶代碼相比,核心部分是非常接近的,我們已經可以和C#一樣用“+=”和“-=”來定制事件和撤消事件定制,并在ObjFireEvent()被調用時收到事件通知,輸出文本。

鑒于篇幅的原因,我們沒有仔細比較兩個版本的eventaddremove訪問器/成員函數,其實二者也是非常類似的,你可以自己試試。C++版的eventaddremove均為virtual的,你可以從event類繼承出來一個MyEvent類,然后重新實現這兩個函數,就可以定制自己的addremove了。這和C#add/remove訪問器的也是非常相像的。

 

三、總結

通過這場“模仿show”我們可以從更深的層次理解C#event機制,更重要的是我們用自己所熟悉的東西(C++,模板類)來模仿并解釋了我們目前還不太熟悉的東西(C#event)。

其實,C#delegate就是C++的函數指針,C# event的核心機制就是C++中的模板(定義event時表現出來)和運算符重載(+=-=和直接把event當做函數調用)的結合體。C#C++中容易出錯的部分用“新特性”封裝了起來,把這部分工作從programmer身上轉移到了compiler身上,讓我們把更多的精力集中到業務邏輯的處理上。

<>

posted on 2012-04-26 17:52 Dino-Tech 閱讀(639) 評論(0)  編輯 收藏 引用

只有注冊用戶登錄后才能發表評論。
網站導航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            欧美新色视频| 在线一区视频| 麻豆视频一区二区| 欧美风情在线观看| 在线亚洲欧美视频| 国产美女精品人人做人人爽| 午夜在线a亚洲v天堂网2018| 久久综合伊人| 亚洲精品在线二区| 国产精品免费小视频| 欧美一区二区在线看| 久久在线免费观看| 99视频在线精品国自产拍免费观看| 日韩亚洲国产欧美| 99国产精品视频免费观看| 欧美电影打屁股sp| 国产精品欧美久久| 亚洲精品国久久99热| 欧美激情成人在线| 亚洲色图综合久久| 浪潮色综合久久天堂| 亚洲激情av| 国产精品美女久久久| 巨乳诱惑日韩免费av| 99热精品在线| 免费成人在线观看视频| 在线亚洲一区二区| 一色屋精品视频免费看| 欧美日韩一区二区视频在线| 欧美在线观看视频| 日韩视频一区二区三区在线播放免费观看 | 一区二区三区欧美视频| 亚洲精品乱码久久久久| avtt综合网| 国模私拍视频一区| 欧美三级欧美一级| 美女久久一区| 亚洲欧美日韩区| 亚洲精品一二三区| 欧美成人精品三级在线观看| 亚洲欧美综合v| 一本久久青青| 91久久精品一区二区三区| 国产欧美一区二区色老头| 欧美日韩理论| 牛人盗摄一区二区三区视频| 久久gogo国模啪啪人体图| 亚洲一区二区三区四区视频| 亚洲激情视频网站| 欧美成年人视频网站| 久久久久久一区二区| 亚洲欧美日本视频在线观看| 99国内精品久久| 亚洲国产精品成人综合| 狠狠色丁香久久婷婷综合_中| 午夜天堂精品久久久久 | 亚洲第一精品电影| 久久久久中文| 欧美中文字幕在线| 亚洲一区网站| 亚洲无线视频| 亚洲一区欧美| 亚洲欧美日韩第一区| 亚洲一区国产一区| 亚洲一级黄色片| 亚洲午夜精品在线| 亚洲午夜精品福利| 亚洲一区二区三区四区视频| 夜夜嗨av一区二区三区网页| 99ri日韩精品视频| 99精品视频免费| 中国av一区| 亚洲中午字幕| 久久不射中文字幕| 久久久久久网址| 蜜乳av另类精品一区二区| 狂野欧美一区| 亚洲国产精品精华液2区45| 欧美激情网友自拍| 亚洲人成在线观看网站高清| 日韩午夜一区| 亚洲男人的天堂在线| 性做久久久久久免费观看欧美| 亚洲国产日韩欧美| 亚洲第一在线| 亚洲每日更新| 亚洲视频免费在线| 欧美一区二区成人6969| 久久久久高清| 欧美激情网友自拍| 国产精品海角社区在线观看| 国产欧美午夜| 亚洲国产午夜| 国产精品99久久久久久久久| 午夜精品久久久久久久蜜桃app| 亚洲人妖在线| 亚洲欧美日本伦理| 久久亚洲综合网| 亚洲激情综合| 亚洲私人影院在线观看| 欧美影院精品一区| 欧美激情视频一区二区三区在线播放| 久久久精品国产免费观看同学| 在线视频亚洲| 久久精品一区二区三区不卡| 欧美激情一区二区三区成人| 欧美日韩中文在线| 黄色另类av| 亚洲天堂av电影| 久久亚洲美女| 一区二区激情视频| 久久久99精品免费观看不卡| 欧美日韩成人综合天天影院| 国产日韩欧美一区二区三区在线观看| 欧美性色视频在线| 在线精品观看| 欧美在线黄色| 亚洲国产成人久久综合一区| 亚洲一区影院| 欧美高清视频www夜色资源网| 欧美二区视频| 国语自产精品视频在线看抢先版结局 | 18成人免费观看视频| 亚洲精品乱码久久久久久久久| 亚洲国产中文字幕在线观看| 午夜久久资源| 亚洲国产日韩欧美综合久久| 欧美一区二区三区久久精品| 欧美日韩国产在线播放| 影音先锋中文字幕一区| 中文网丁香综合网| 欧美电影免费网站| 欧美专区第一页| 国产精品视频你懂的| 日韩亚洲精品视频| 你懂的视频一区二区| 亚洲一区二区黄| 欧美日韩国产综合一区二区 | 国产精品久久久久久av福利软件 | 亚洲第一网站| 午夜精品影院在线观看| 欧美日韩亚洲网| 99re亚洲国产精品| 亚洲国产91| 免费在线亚洲| 亚洲国产另类久久久精品极度| 日韩视频一区二区三区| 欧美成人免费在线观看| 香蕉久久久久久久av网站| 欧美视频一二三区| 在线视频你懂得一区二区三区| 亚洲欧美日韩国产综合| 亚洲精品资源美女情侣酒店| 欧美风情在线观看| 91久久精品日日躁夜夜躁欧美| 一区二区三区精品视频| 亚洲欧洲一区二区三区在线观看 | 亚洲欧美另类中文字幕| 欧美色综合网| 亚洲一区二区三区精品动漫| 亚洲精品护士| 欧美日韩国产精品专区| 在线视频日韩| 中文国产成人精品久久一| 国产精品不卡在线| 亚洲自拍16p| 午夜久久久久久久久久一区二区| 欧美 日韩 国产精品免费观看| 欧美午夜精品久久久久久人妖| 国内在线观看一区二区三区| 久久精品国产69国产精品亚洲| 亚洲国产人成综合网站| 欧美女同在线视频| 亚洲午夜久久久久久久久电影院| 久久精品人人做人人爽电影蜜月| 亚洲第一天堂av| 欧美日韩国产美女| 亚洲综合视频一区| 欧美一区二区三区成人| 黄色成人在线| 91久久久在线| 国产精品久久久久9999| 欧美亚洲综合网| 久久久国产成人精品| 亚洲欧洲日本mm| 一区二区欧美亚洲| 国产一区二区三区在线观看网站| 亚洲视频axxx| 午夜精品久久久久久久久久久久| 欧美大片免费久久精品三p| 这里只有精品视频在线| 亚洲欧美日韩精品久久久久| 国内免费精品永久在线视频| 欧美韩日亚洲| 国产精品久久看| 免费成人黄色片| 欧美涩涩视频| 欧美成人一品| 国产精品一区免费在线观看| 免费成人黄色片|