天天看點

NET委托和事件

1.委托的定義

委托的聲明原型是

delegate<函數傳回類型><委托名>(<函數參數>)

例子: public delegate void CheckDelegate(int number);//定義了一個委托

CheckDelegate,它可以注冊傳回void類型且有一個int作為參數的函數

這樣就定義了一個委托,但是委托在.NET内相當于聲明了一個類,類如果不執行個體化為對象,很多功能是沒有辦法使用的,

委托也是如此。

2.委托的執行個體化

委托執行個體化的原型是

<委托類型><執行個體化名>=new<委托類型>(<注冊函數>)

例子: CheckDelegate _checkDelegate = CheckMod;//用函數CheckMod執行個體化上面的

CheckDelegate 委托為_checkDelegate

現在我們就可以像使用函數一樣來使用委托了,在上面的例子中現在執行

_checkDelegate()就等同于執行CheckMod(),最關鍵的是現在函數CheckMod相當于放在了變量當中,

它可以傳遞給其它的CheckDelegate引用對象,而且可以作為函數參數傳遞到其他函數中,也可以作為函數的

傳回類型。

2.用匿名函數初始化委托

匿名函數初始化委托的原型:

<委托類型> <執行個體化名> = new <委托類型>(delegate(<函數參數>){函數體});

也可以是<委托類型> <執行個體化名>=delegate(<函數參數>){函數體};

3.泛型委托

委托也支援泛型的使用

泛型委托原型:

delegate <T1> <委托名><T1,T2,T3...> (T1 t1,T2 t2,T3 t3...)

例子:

delegate T2 A<T1,T2>(T1 t);//定義有兩個泛型(T1,T2)的委托,T2作為委托函數傳回類型,T1作為委托函數參數類型

例1:

class Program

{

public delegate void Func1(int i);

public delegate int Func2(int i);

static void PrintNumber(int i)

{

Console.WriteLine(i);

}

static void Main(string[] args)

{

Func1 _func = new Func1(PrintNumber);

_func(5);

Console.ReadLine();

}

}

例2:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

namespace ConsoleApplication1

{

class Program

{

delegate void Func1(int i);

delegate int Func2(int i);

static Func1 t1 = new Func1(delegate(int i)

{

Console.WriteLine(i);

});

static Func2 t2;

static void Main(string[] args)

{

t2 = delegate(int j)

{

return j;

};

t1(2);

Console.WriteLine(t2(1));

}

}

}

例3:

class Program

{

//泛型委托

public delegate T2 A<T1,T2>(T1 t);

static int test(int t){

return t;

}

static void Main(string[] args)

{

A<int,int> a = test;

Console.WriteLine(a(5));

Console.ReadKey();

}

}

例4:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

namespace ConsoleApplication3

{

public delegate int DelMath(int i);//定義委托類DelMath,該委托傳入一個int類型參數,

//傳回一個int類型參數。

class Program

{

static DelMath dMath;//通過委托類型DelMath定義委托執行個體dMath

static event DelMath eMath;//通過委托類型DelMath定義事件執行個體eMath

/// <summary>

/// 将傳入的參數i自加後作為函數傳回值

/// </summary>

/// <param name="i"></param>

/// <returns></returns>

static int IncMath(int i)

{

i++;

Console.WriteLine("IncMath has been invoked!");

return i;

}

static int DecMath(int i){

i--;

Console.WriteLine("DecMath has been invoked!");

return i;

}

static void Main(string[] args)

{

int i = 10;//定義int 型變量i,初始化為10

dMath += IncMath;//先将IncMath函數注冊到委托執行個體dMath

dMath += DecMath;//再将DecMath函數注冊到委托執行個體dMath

Console.WriteLine("dMath returned:" + dMath(i).ToString());

eMath += IncMath;

eMath += DecMath;

Console.WriteLine("eMath returned:" + eMath(i).ToString());

Console.ReadKey();

}

}

}

4.事件

事件定義

event<委托類型> 事件名

委托: public delegate void CheckDelegate(int i);

例子: 事件:public event CheckDelegate checkEvent;

上面的例子聲明了個事件叫checkEvent你會發現它隻比聲明委托執行個體前多了個關鍵字event

聲明了事件後就可以執行個體化事件,注冊函數到事件,解除事件函數注冊其方法和委托的步驟如出一轍:

例子:checkEvent+=new CheckDelegate(CheckMod);//将函數CheckMod注冊到事件checkEvent上

checkEvent+=CheckMod;//.net 2.0開始支援這種方法

checkEvent-=new CheckDelegate(CheckMod);//将函數CheckMod解除對事件checkEvent的注冊

checkEvent-=CheckMod;//.net 2.0開始支援這種方法

5.委托與事件的聯系:

從種種迹象都可以看出事件和委托執行個體是那麼的相似,那麼為什麼不直接用委托還要用到事件呢?

其實事件就是對委托的封裝。

就如同c#類中屬性對字段的封裝一樣,其封裝後可以在委托上封裝更複雜的邏輯,下面我們來看c#中事件的兩種聲明方式,來了解事件對委托的封裝

1)顯式聲明事件

其實顯式聲明事件就是要自己來手動實作隐式聲明事件的一個委托執行個體

和兩個函數:

event<委托類型> 事件名

{

add

{

//将函數注冊到自己定義的委托執行個體

}

remove

{

//解除函數對自己定義的委托執行個體的注冊

}

}

例1 private CheckDelegate _checkDelegate;

public event CheckDelegate checkEvent

{

add{

_checkDelete = Delegate.Combine(_checkDelete,value ) as CheckDelegate;

}

remove

{

_checkDelete = Delegate.Remove(_checkDelete, value) as CheckDelegate;

}

}

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

namespace ConsoleApplication4

{

public class ClassLibrary

{

public delegate void CheckDelegate(int number);

public event CheckDelegate checkEvent;

public void WriteInner(int n)

{

Console.WriteLine(n.ToString());

}

public void InitEvent()

{

checkEvent = WriteInner;//對事件從新指派

}

public void Exec(int n)

{

checkEvent(n);

}

}

}

例2.

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

namespace ConsoleApplication4

{

class Temp //定義此類是為了在代碼中展示函數對委托和事件的另外一種注冊方式

{

public delegate void TempDelegate(int u);

public static TempDelegate td;

public static event TempDelegate ed;

}

class Program

{

private static void CheckMod(int number)

{

if(number % 2==0)

{

Console.WriteLine("輸入的是偶數");

}

else

{

Console.WriteLine("輸入的不是偶數");

}

}

private static void CheckPositive(int number)

{

if (number > 0)

{

Console.WriteLine("輸入的是正數");

}

else

{

Console.WriteLine("輸入的不是正數");

}

}

static void Main(string[] args)

{

ClassLibrary cl = new ClassLibrary();

// cl.checkEvent = new ClassLibrary.CheckDelegate(CheckMod);

cl.checkEvent += CheckMod;

cl.checkEvent += CheckPositive;

Console.WriteLine("cl的結果");

cl.Exec(50);

Console.ReadKey();

}

}

}

轉載于:https://www.cnblogs.com/gylhaut/p/5324397.html

c#