第五章:代理
代理實現的是象c++等語言的指標功能,不同於函數指標,代理是一種物件導向、安全類型的。代理事派生於公用基類(system)的一種參考類型,方法被壓入一個代理中,對於執行個體方法被稱為執行個體的組成實體或關於執行個體的方法,而靜態方法,被稱為類的組成實體或類方法。代理的強大功能是它可以自動的匹配方法,而不管其類型。
寫一個代理包括三個步驟:
寫代理、執行個體化、調用。
代理的聲明使用以下文法:
delegate void SimpleDelegate();
執行個體化一個代理
class Test
{
static void F() {
System.Console.WriteLine("hello world");
}
static void Main() {
SimpleDelegate d = new SimpleDelegate(F);//將方法壓入
d();//通過代理;
F();//不通過代理;
}
}
最後讓我們調用她
void MultiCall(SimpleDelegate d, int count) {
for (int i = 0; i < count; i++)
d();
}
}
我們可以看到對於方法的調用是通過代理來完成的,調用時並不需要知道被調用她的類型。代理在我看來好比是對象要一件事她不直接地調用這個方法,而是通過一個中間人去調用她。
下面就代理的強大功能進行詳細介紹:首先然我們實現一個這樣的功能,考慮一下該如何用指向基類的對象調用子類的成員函數。在這裡程式員是不是點懷戀指標了,不過在c#中這樣的功能完全也可實現的,使用一個單獨的代理我們可以完成這項功能。以下代碼來自Timothy A. Vanover文章。
namespace DelegatesCS
{
using System;
public class Wisdom //包含代理的類
{
public delegate string GiveAdvice();
public string OfferAdvice(GiveAdvice Words)
{
return Words();
}
}
public class Parent //基類
{
public virtual string Advice()
{
return("Listen to reason");
}
~Parent() {}
}
public class Dad: Parent //子類
{
public Dad() {}
public override string Advice()
{
return("Listen to your Mom");
}
~Dad() {}
}
public class Mom: Parent //子類
{
public Mom() {}
public override string Advice()
{
return("Listen to your Dad");
}
~Mom() {}
}
public class Daughter //不繼承與基類的類
{
public Daughter() {}
public string Advice()
{
return("I know all there is to life");
}
~Daughter() {}
}
public class Test
{
public static string CallAdvice(Parent p)//使用基類
{
Wisdom parents = new Wisdom();
Wisdom.GiveAdvice TeenageGirls = new Wisdom.GiveAdvice(p.Advice);//將Advice方法委託給TeenageGirls委派物件
return(parents.OfferAdvice(TeenageGirls));
}
public static void Main()
{
Dad d = new Dad();
Mom m = new Mom();
Daughter g = new Daughter();
//以下兩個為衍於基類的類
Console.WriteLine(CallAdvice(d));
Console.WriteLine(CallAdvice(m));
//以下為未衍於基類的類,如果調用將出錯。
//Console.WriteLine(CallAdvice(g));
}
}
}
代理 二
1〉事件
上一章講解了有關代理的基本應用,本章將繼續講解深入代理的使用。這裡我們講解使用代理來處理事件。關於事件在另一章進行詳細講解。處理事件在c#中對比c++和vb來說更聰明,你可以寫代理然後寫事件處理者,事件處理者是一種定義在控制項和表單類中的重載的公用事件。我們在以下的例子中將看到代理在事件中的應用。
1。寫代理
我想處理按一下滑鼠事件和在按一下滑鼠左鍵或右鍵處理一些代碼。寫下面的代碼在你的初始控制項函數中。
this.MouseDown += new System.WinForms.MouseEventHandler(this.Form_MouseDown);
2. 寫事件
現在你可以寫事件處理,你的事件的輸出參數將返回表單的滑鼠事件參數的詳細內容。以下時滑鼠事件參數成員
MouseEventArgs members
Button 指示哪一個鍵被壓,分為左、右、中、無 。
Clicks 指示滑鼠壓下次數及釋放狀態。
Delta 指示滑鼠轉動數量計數
X 滑鼠點擊x座標點
Y 滑鼠點擊y座標點
Event Handler
private void Form_MouseDown(object sender, System.WinForms.MouseEventArgs e)
{
switch (e.Button)
{
case MouseButtons.Left:
MessageBox.Show(this,"Left Button Click");
break;
case MouseButtons.Right:
MessageBox.Show(this,"Right Button Click" );
break;
case MouseButtons.Middle:
break;
default:
break;
}
}
在你的WinForm中測試你的程式,你會看到通過代理事件被關聯了。
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
class I
{
public I(){}
~I() {}
public void IDoLoveYou()
{System.Console.WriteLine("I do love You");}
public void why(){System.Console.WriteLine("why?");}
}
class HER
{
public HER(){}
~HER() {}
public void IDo()
{System.Console.WriteLine("...............");}
public void slient(){System.Console.WriteLine(".........");}
}
class TELEPHONE
{public delegate void heartchat();
public TELEPHONE(){}
~TELEPHONE(){}
public void hello(){System.Console.WriteLine("yesterday night,i telephone to my girlfriend"); }
}
class chat{
static void Main() {
I i=new I();
HER her=new HER();
TELEPHONE telephone =new TELEPHONE();
telephone.hello();
TELEPHONE.heartchat tell=new TELEPHONE.heartchat(i.IDoLoveYou);
tell();
TELEPHONE.heartchat answer=new TELEPHONE.heartchat(her.IDo);
answer();
TELEPHONE.heartchat ask=new TELEPHONE.heartchat(i.why);
ask();
TELEPHONE.heartchat noanswer=new TELEPHONE.heartchat(her.slient);
noanswer();
}
}