淺析C#---委託和事件,
淺析C#---委託和事件
在C#開發中,有時我們需要實現這樣的情況:只要新添加一個對象,就要執行一系列的方法。如果每次挨個調用,這樣既浪費時間,又造成代碼冗餘。這個時候我們就可以使用委託來建立一個方法鏈條,設定好後,可以讓一個對象依次去執行這個鏈條上的各個方法。這樣的結果就是:簡化了代碼,提高了效率,提高了代碼的可維護性。
究竟什麼是委託呢?事件有何委託有什麼關係呢?
一、定義
委託是一個類,它定義了方法的類型,使得可以將方法當作另一個方法的參數來進行傳遞,這種將方法動態地賦給參數的做法,可以避免在程式中大量使用If-Else(Switch)語句,同時使得程式具有更好的可擴充性。
事件是一種特殊的委託,它在某些操作哦 發生時自動地發出通知。
二、使用
2.1、委託的使用
委託是一個能夠引用方法的對象,能夠調用它所指的方法。而且,在成宿運行七屆,同一個委託可以條用不同的方法,只要改變它的引用的方法即可。所有委託類型的基類是System.Delegate類。
2.1.1、聲明
像其他類一樣,委託在使用之前也需要聲明。委託型別宣告將建立一個協定,該協定指定一個或多個方法簽名。委託是委託類型的執行個體,它可以引用靜態方法或執行個體方法。
文法:delegate-modifiers(修飾符) delegate(需使用的關鍵字) return-type(傳回型別) identifier(類型名稱)
2.1.2、註冊方法
如果一個方法要註冊到委託中,則該方法的簽名必須與該委託所指定的簽名完全符合(即兩者傳回型別和方法參數須相同,參數具體的名稱可以不同)
2.1.3、執行個體化委託
委託作為一個類,在使用前必須有執行個體化的過程。其執行個體化可以建立委託類型的執行個體,並向該執行個體註冊方法列表。委託類型的執行個體的方法列表可以為靜態方法,執行個體方法或者另外的委託。
下面可以通過一個執行個體我們來理解一下。
internal delegate int MyDelegate(int i); //聲明委託
class Program
{
//聲明一個執行個體方法Method1(int i)
public int Method1(int i)
{
Console.WriteLine("調用執行個體方法Method1(int i)");
return i;
}
//聲明一個靜態方法Method2(int i)
public static int Method2(int i)
{
Console.WriteLine("調用執行個體方法Method2(int i)");
return i;
}
static void Main(string[] args)
{
Program p =newProgram();
MyDelegate dDelegate =newMyDelegate(p.Method1); //將Method1註冊到dDelegate中,並執行個體化dDelegate
int i = dDelegate(10);
Console.WriteLine("i的值為:" + i);
MyDelegate dMyDelegate =newMyDelegate(Program.Method2); //將Method2註冊到dMyDelegate中,並執行個體化dDelegate
int j =dMyDelegate(20);
Console.WriteLine("j的值為:" + j);
Console.ReadKey();
}
}
2.1.4構建方法列表
使用委託可以將多個方法綁定到同一個委託變數,當調用此變數是,可以一次調用所有綁定的方法。
方法列表可以包含一個或多個方法。
2.1.5調用
委託是一個方法鏈條,因此調用委託執行個體就相當於調用了該委託執行個體半酣的所有方法。如果一個調用列表包含多個方法是,當該委託執行個體被調用是,它將按照調用列表中的方法註冊順序依次調用每一個方法(通過下面例子的運行結果可以看出)。
下面我們用一個例子說明一下
internal delegate int MyDelegate(int i); //聲明委託
class Program
{
//聲明一個執行個體方法Method1(int i)
public int Method1(int i)
{
Console.WriteLine("調用執行個體方法Method1(int i)");
return i;
}
//聲明一個靜態方法Method2(int i)
public static int Method2(int i)
{
Console.WriteLine("調用執行個體方法Method2(int i)");
return i;
}
static void Main(string[] args)
{
Program p =newProgram();
MyDelegate dDelegate1 =newMyDelegate(p.Method1); //將Method1註冊到dDelegate中,並執行個體化dDelegate
MyDelegate dDelegate2 =newMyDelegate(Program.Method2); //將Method2註冊到dMyDelegate中,並執行個體化dDelegate
MyDelegate dDelegate3 =dDelegate1 + dDelegate2; //給委託dDelegate3執行個體註冊方法
MyDelegate dDelegate4 =dDelegate3 - dDelegate2; //給委託dDelegate4執行個體移除方法
int i1 =dDelegate1(20);Console.WriteLine("i1的值為:" + i1);
int i2 = dDelegate2(20);Console.WriteLine("i2的值為:" + i2);
int i3 =dDelegate3(20);Console.WriteLine("i3的值為:" + i3);
int i4 =dDelegate4(20);Console.WriteLine("i4的值為:" + i4);
Console.ReadKey();
}
}
執行結果:
2.2事件的使用
事件是某些操作發生時自動地發出通知。時間構建在委託的基礎上,它是一種訊號機制。程式員可以通過提供事件處理常式為相應的時間添加可執行代碼。當事件觸發時,將調用改時間事先定義的方法。
2.2.1聲明
事件是一種特殊類型的委託,它包含兩個參數:指示事件來源的“對象源”(sender)參數和封裝事件的其他任何相關資訊的e參數。
事件的聲明分為:(1)聲明事件的委託;(2)聲明事件的本身
2.2.2註冊和移除
一個事件聲明之後,改時間的預設值為null,如果希望該事件執行事先指定的操作,則首先向該事件註冊方法列表。註冊事件可以使用“+=”運算子,同時我們也可以移除事件(使用“-=”運算子)
2.2.3調用
聲明一個事件之後,如果沒有向該事件註冊方法那麼該事件的值為空白。因此在呼叫事件時,往往需要檢查該事件是否為空白。
通過下面一個例子我們來看看事件是如何使用的。
namespace 事件
{
//聲明委託
public delegate void EventHandler(object sender, EventArgs e);
class Program
{
//聲明一個事件
public event EventHandler Print;
//聲明一個方法
public void Method1(object sender, EventArgs e)
{
Console.WriteLine("方法F1()");
}
//聲明一個方法
public void Method2(object sender, EventArgs e)
{
Console.WriteLine("方法F2()");
}
static void Main(string[] args)
{
Program program =newProgram();
program.Print += new EventHandler(program.Method1); //註冊Method1方法
program.Print += new EventHandler(program.Method2); //註冊Method2方法
Console.WriteLine("事件中的方法列表:");
if (program .Print !=null)
{
program.Print(null,null);
}
Console.WriteLine("");
program.Print -= new EventHandler(program.Method1); //移除Method1方法
Console.WriteLine("移除方法Method1之後:");
if (program.Print != null)
{
program.Print(null,null);
}
Console.ReadKey();
}
}
}
運行結果: