www.日本精品,久久中文视频,中文字幕第一页在线播放,香蕉视频免费网站,老湿机一区午夜精品免费福利,91久久综合精品国产丝袜长腿,欧美日韩视频精品一区二区

樂(lè)高ev3機(jī)器人編程自學(xué) [代理及其編程方法]

發(fā)布時(shí)間:2020-02-16 來(lái)源: 散文精選 點(diǎn)擊:

  摘要:在C#語(yǔ)言中,可以用代理(Delegate)來(lái)動(dòng)態(tài)地調(diào)用不同的函數(shù)。本文針對(duì)代理的基本概念、用代理編程的基本結(jié)構(gòu)及多重代理進(jìn)行討論,并通過(guò)實(shí)例程序進(jìn)行必要的說(shuō)明。
  關(guān)鍵詞:函數(shù)指針;代理;多重代理
  中圖分類號(hào):TP312 文獻(xiàn)標(biāo)識(shí)碼:A
  
  1 代理的基本概念
  
  在C/C++中,函數(shù)調(diào)用有兩種方式:一種是通過(guò)函數(shù)名直接調(diào)用;另一種是利用指向函數(shù)的指針進(jìn)行調(diào)用。指向函數(shù)的指針又簡(jiǎn)稱為函數(shù)指針。采用函數(shù)指針調(diào)用函數(shù),可以達(dá)到通過(guò)一個(gè)函數(shù)指針調(diào)用多個(gè)功能不同、但函數(shù)的參數(shù)及返值類型一致的函數(shù)。
  1.1 函數(shù)指針
  在C/C++中,函數(shù)名表示函數(shù)在存儲(chǔ)區(qū)域的首地址,即是函數(shù)執(zhí)行的入口地址。在程序中調(diào)用一個(gè)函數(shù)時(shí),程序控制流程將轉(zhuǎn)移到以該函數(shù)名為入口地址的地方執(zhí)行該函數(shù)。
  函數(shù)指針定義的一般形式是:
  數(shù)據(jù)類型(*函數(shù)指針名)(參數(shù)表);
  其中數(shù)據(jù)類型是函數(shù)指針?biāo)赶虻暮瘮?shù)所具有的返值類型,參數(shù)表是被調(diào)函數(shù)所具有的參數(shù)表。
  一般來(lái)講,函數(shù)指針得到某個(gè)函數(shù)名的賦值,程序?qū)⒄{(diào)用該函數(shù);在函數(shù)指針作為函數(shù)的形參時(shí),需要進(jìn)行取內(nèi)容的運(yùn)算才能調(diào)用對(duì)應(yīng)的函數(shù)。例如:
  exe(int x,int y,int (*func)())
  { return((*func)(x,y));}
  在上述exe函數(shù)中,int (*func)()是函數(shù)指針,而“((*func)(x,y));”程序?qū)⑥D(zhuǎn)向由func所指向的函數(shù)去執(zhí)行,其參數(shù)是x和y。
  使用函數(shù)指針編程方法一般為:定義相應(yīng)的函數(shù);定義函數(shù)指針;通過(guò)某種操作使函數(shù)指針得到函數(shù)名的賦值;最后連同參數(shù)調(diào)用相應(yīng)的函數(shù)。
  1.2 代理及其相關(guān)概念
  在C#中,代理(delegate)的作用類似于C/C++中的函數(shù)指針。C#中的方法類似于C/C++中的函數(shù),其方法名也是一個(gè)物理地址。方法的入口地址可以賦給“代理”,進(jìn)而通過(guò)“代理”調(diào)用該方法;且同一個(gè)代理可以調(diào)用多個(gè)不同的方法。使用代理可以在程序的運(yùn)行期間動(dòng)態(tài)地調(diào)用所需的函數(shù)。
  代理定義的一般格式為:
  [訪問(wèn)控制修飾符] delegate返值類型 代理名([形式參數(shù)表]);
  其中:訪問(wèn)控制修飾符可以是new、public、protected、internal和private。new修飾符表明當(dāng)前定義的代理將隱藏繼承來(lái)的同名代理;public修飾符表明所有對(duì)象都可以訪問(wèn)該定義的代理;protected修飾符表明定義該代理的類及其子類可以訪問(wèn)該代理;internal修飾符只有代理所屬的工程項(xiàng)目的成員可以訪問(wèn)該代理;private修飾符表明只有定義該代理的類才能訪問(wèn)該代理。
  delegate是定義代理的關(guān)鍵字。代理名是符合C#的任意合法的標(biāo)識(shí)符。返值類型是指該代理所調(diào)用方法的返值類型。形式參數(shù)表用于指出代理所調(diào)用方法的參數(shù)表。
  例如,在一個(gè)類中定義一個(gè)代理MyDel_ egate:
  classMyClass
  { ……
  public delegate void MyDelegate(string s);
  ……
  }
  在上述代理定義中的void表示該代理指向的方法不返回任何值,string s表示該代理所指向的方法將接受一個(gè)字符串參數(shù)。
  在C#中,定義一個(gè)代理MyDelegate, C#編譯器將根據(jù)代理的定義語(yǔ)句自動(dòng)生成一個(gè)從System.MulticastDelegate類派生的子類MyDelegate。
  
  2 使用代理的編程結(jié)構(gòu)
  
  代理類似于C/C++的指向函數(shù)的指針,但是代理的使用范圍比函數(shù)指針更加廣泛。在C中,函數(shù)只有外部和靜態(tài)函數(shù)兩種,它們都屬于靜態(tài)函數(shù)的范疇;在C ++中,函數(shù)指針只能引用靜態(tài)方法,而代理不僅可以引用靜態(tài)方法,還可以引用對(duì)象的實(shí)例方法。
  2.1 使用代理的編程結(jié)構(gòu)
  使用代理編程和在C/C++中使用函數(shù)指針類似,一般有:定義將要由代理調(diào)用的方法;聲明一個(gè)代理;定義delegate處理的函數(shù);創(chuàng)建實(shí)例并調(diào)用相應(yīng)方法。
 。1)定義擬調(diào)用的方法
  該類方法的函數(shù)返值類型,函數(shù)形參的參數(shù)類型、個(gè)數(shù)及參數(shù)的順序,決定了定義delegate類型代理時(shí)的相應(yīng)參數(shù)。例如:
  public static string FunctionA
 。╯tring name) {……}
  public static string FunctionB
 。╯tring name) {……}
 。2)聲明一個(gè)代理
  該代理的返值類型,參數(shù)的類型、個(gè)數(shù)及參數(shù)的順序都必須與擬調(diào)用的方法的返值類型,形參類型、個(gè)數(shù)及參數(shù)的順序完全相同。例如:
  public delegate string MyDelegate (stringname);
 。3)定義delegate類型處理的函數(shù)
  定義delegate類型處理的函數(shù),并在此函數(shù)中通過(guò)delegate類型調(diào)用定義的方法。
  public static void MethodA(MyDelegateMe)
  {Console.WriteLine(Me(“張三”));}
  (4)創(chuàng)建實(shí)例并調(diào)用方法
  由于聲明一個(gè)delegate類型的代理在編譯時(shí)將被轉(zhuǎn)換成一個(gè)MulticastDelegate類的派生類,因此在使用代理時(shí),必須要先創(chuàng)建該類的實(shí)例,并把它與一個(gè)方法關(guān)聯(lián)。
  MyDelegate a=new MyDelegate (FunctionA)
  本語(yǔ)句的含義是:a引用指向方法FunctionA的程序代碼段。
  通過(guò)delegate處理函數(shù)調(diào)用相應(yīng)的方法。MethodA(a);
  2.2 使用代理編程實(shí)例
  using System;
  namespace ConDelegatejl
  { public class Test
  { //第一步:聲明委托
   public static string FunctionA(string name)
   {return“A say Hello to”+name;}
   public static string FunctionB(string name)
   {return “B say Hello to ”+name;}
   //第二步:定義被調(diào)用的方法
  public delegate string MyDele gate(string name);
  //第三步:定義delegate類型處理函數(shù)
  public static void MethodA (MyDelegate Me)
  {Console.WriteLine(Me(“張三”));}
   public static void Main()
  { //第四步:創(chuàng)建實(shí)例,
  //準(zhǔn)備調(diào)用的方法名
  MyDelegate a = new MyDelegate (FunctionA);
  MyDelegate b = new MyDelegate (FunctionB);
  MethodA(a); MethodA(b); Console.Read();
  }
  }
  上述程序的運(yùn)行結(jié)果如下圖所示。
  
  
  3 多重代理及其實(shí)現(xiàn)
  
  在C#語(yǔ)言中,每一個(gè)代理實(shí)例(對(duì)象)都含有一個(gè)調(diào)用鏈表,該鏈表可以包含多個(gè)該代理要調(diào)用的方法,此種機(jī)制用于一個(gè)代理實(shí)例可以調(diào)用多個(gè)方法,也就是多重代理(多播)。多播要?jiǎng)?chuàng)建方法鏈表,當(dāng)調(diào)用代理時(shí),所有被鏈接的方法都會(huì)被自動(dòng)地調(diào)用。
  3.1 Delegate類和MulticastDelegate類
  所有的代理類都是由MulticastDele gate類派生的,而MulticastDelegate類又是由Delegate類派生的,它們都位于System命名空間下。
  Delegate類有兩個(gè)公用的只讀屬性:
  Method屬性:本屬性用于獲得代理實(shí)例要調(diào)用的靜態(tài)方法?梢杂萌缦麓a獲得代理對(duì)象所調(diào)用的方法名。
  stringMethodName=代理名.Method;
  Target屬性:該屬性可以獲得代理對(duì)象所在的類;如果代理調(diào)用的是靜態(tài)方法,其返值為null,否則將返回代理實(shí)例所調(diào)用方法所在類名。如下代碼可以獲得代理調(diào)用方法所在類的名稱。
  stringObjType=代理名.Target;
  如果代理調(diào)用多個(gè)方法,則該屬性將返回調(diào)用列表中最后一個(gè)實(shí)例方法所在的類名。
  3.2 MulticastDelegate類實(shí)現(xiàn)多重代理的機(jī)制
  從MulticastDelegate類派生的用戶代理實(shí)例中含有一個(gè)調(diào)用鏈表,該鏈表將由多個(gè)代理實(shí)例組成,其中每個(gè)代理實(shí)例都封裝一個(gè)相應(yīng)的方法,也就是一個(gè)代理實(shí)例可以同時(shí)調(diào)用多個(gè)方法。代理實(shí)例通過(guò)_prev私有指針來(lái)連接多個(gè)代理構(gòu)成的鏈表,私有指針_target和_methodPtr用于指向代理實(shí)例調(diào)用的實(shí)例和方法。
  每創(chuàng)建一個(gè)新的代理實(shí)例時(shí),指針_prev將被設(shè)置為null,表示鏈表中沒(méi)有其它的代理實(shí)例。而當(dāng)用戶使用Combine方法(或+=運(yùn)算符)把另一個(gè)代理實(shí)例合并到該調(diào)用鏈表中時(shí),則將先創(chuàng)建一個(gè)含有_target和_methodPtr值的新實(shí)例,然后把該實(shí)例的_prev設(shè)置為調(diào)用鏈表的頭實(shí)例,即從調(diào)用鏈表的頭插入新的實(shí)例?梢允褂肦emove方法(或-=運(yùn)算符)從一個(gè)調(diào)用鏈表中刪除一個(gè)代理實(shí)例。
  3.3 多重代理編程的實(shí)現(xiàn)
  多重代理(或多播)具有創(chuàng)建方法鏈表的能力,當(dāng)調(diào)用代理時(shí),所有被鏈接的方法都會(huì)被自動(dòng)調(diào)用,也就是多播可以在一次代理調(diào)用中調(diào)用方法鏈表上的所有方法。創(chuàng)建多播調(diào)用鏈表的方法是:先實(shí)例化一個(gè)代理,然后使用“+=”運(yùn)算符把方法添加到調(diào)用鏈表中;也可以使用“-=”運(yùn)算符從調(diào)用鏈表中刪除一個(gè)方法。
  下面程序說(shuō)明了多重代理編程的實(shí)現(xiàn)方法。
  using System;
  using System.Collections.Generic;
  using System.Text;namespace ConDelegatej2
  {
   delegate void StringDelegate(
  ref string str);//定義一個(gè)代理
   class stringops//字符串操作類
   { //定義三個(gè)字符串操作方法
   static void ReplaceSpaces(ref string s)
  { Console.WriteLine("用連字符替換
  空格操作:");
  s = s.Replace(" ", "_");
  }
  static void RemoveSpaces(ref string s)
  { string temp = "";int i;
  Console.WriteLine("刪除空格操作:");
  for(i=0; i=0;j--)
  temp += s[j];
   s = temp;
   }
  static void Main(string[]args)
  {//創(chuàng)建一個(gè)代理
  StringDelegate strdelegate;
  StringDelegate replacesp=new
  StringDelegate(ReplaceSpaces);
  StringDelegate removes =new
   StringDelegate(RemoveSpaces);
  StringDelegate reversestr=new StringDelegate(Reverse);
  string str = "Iam astudent.";
  //代理指向一個(gè)函數(shù)
  strdelegate =replacesp;
  strdelegate += reversestr;//多播關(guān)聯(lián)
  strdelegate(ref str );//調(diào)用多播
  Console.WriteLine("操作字符串的結(jié)果為:"+str);
  Console.WriteLine();
  strdelegate-=replacesp;//去除replacesp
  strdelegate += RemoveSpaces;
  str ="你是一個(gè)計(jì)算機(jī)教師.";
  strdelegate (refstr);
  Console.WriteLine("字符串操作結(jié)果是:"+str);
   Console.WriteLine ();Console.Read();
  }
   }
  }
  上述程序的運(yùn)行結(jié)果如下所示。
  
  
  4 結(jié)束語(yǔ)
  
  代理是C#語(yǔ)言提供動(dòng)態(tài)調(diào)用函數(shù)的一種方法;多重代理解決了用一個(gè)代理一次調(diào)用多個(gè)方法的技術(shù)。不過(guò)代理的多播有一個(gè)限制:方法鏈表中的方法必須具有相同的參數(shù),而且這些方法的返回值類型要是void類型。
  代理也為用戶程序利用屬性驅(qū)動(dòng)事件程序的編程提供了有力的方法。
  
   參考文獻(xiàn)
  [1]唐大仕編著. C#程序設(shè)計(jì)教程[M]. 北京: 清華大學(xué)出版社; 北方交通大學(xué)出版社, 2003.
  [2]邵鵬鳴編著. Visual C#程序設(shè)計(jì)基礎(chǔ)教程[M]. 北京: 清華大學(xué)出版社, 2005.

相關(guān)熱詞搜索:編程 代理 方法 代理及其編程方法 編程通訊線代理 可編程觸摸屏代理

版權(quán)所有 蒲公英文摘 m.newchangjing.com