成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

再議C#方法中的反射方式和委托方式

開發 后端
我們將要談到的是C#方法中的反射方式和委托方式,文中還將給出具體代碼,以方便大家測試和實踐。

  在開發過程中對靜態方法的調用是通過類型名后面加個點而后是調用方法的名稱,對類型實例方法的調用是通過new一個對象,而后點加方法名稱,這是最熟悉不過的兩種方式。還可以通過讀取CLR元數據,利用反射進行方法調用。在利用反射方式調用方法時,最重要的兩個類是System.Type和System.Reflection.MethodInfo。用MethodInfo類型的Invoke方法調用方法,必須傳入目標對象實例的引用。如下:

  1.   publicclassCalculate  
  2.   {  
  3.   //使用反射可以調用私有方法  
  4.   private intAdd(intleftNum, intrightNum)  
  5.   {  
  6.   returnleftNum + rightNum;  
  7.   }  
  8.  }  
  9.   classProgram  
  10.   {  
  11.   staticvoidMain(string[] args)  
  12.   {  
  13.   //用type.getmethod的方法獲取類型方法,BindingFlags設置查找方法的范圍  
  14.   //本例是公有方法,私有方法而且是非靜態的才被查找,如果要查找靜態方法  
  15.   //需要設置BindingFlags.Static  
  16.   MethodInfomethod = typeof(Calculate).GetMethod("Add", BindingFlags.Public  
  17.   | BindingFlags.NonPublic  
  18.   |BindingFlags.Instance);  
  19.   if(method == nullreturn 
  20.   //調用方法的參數  
  21.   object[] paras ={ 10, 20 };  
  22.   //目標對象實例:new Calculate()  
  23.   objectresult = method.Invoke(newCalculate(), paras);  
  24.   Console.WriteLine(result);  
  25.   Console.ReadLine();  
  26.   }  
  27.   } 

  委托方式

  任何對象都可以調用委托,只要方法返回值以及方法簽名和委托聲明一樣就行。

  通過閱讀CLR源代碼,整理了委托類的重要字段和幾個常用方法,自定義的委托類型都派生于MulticastDelegate。

  1.   publicabstractclassDelegate: ICloneable,ISerializable  
  2.   {  
  3.   // 調用目標對象,實例方法為類型實例引用,靜態方法則為null  
  4.   internalObject_target;  
  5.   //指向調用方法  
  6.   internalIntPtr_methodPtr;  
  7.   //委托構造器  
  8.   protectedDelegate(Objecttarget, Stringmethod)  
  9.   {  
  10.   //省略,具體看以查看clr源代碼  
  11.   }  
  12.   publicstaticDelegateCreateDelegate(Typetype, Objecttarget, Stringmethod)  
  13.   {  
  14.   //省略,具體看以查看clr源代碼  
  15.   }  
  16.   publicstaticDelegateCreateDelegate(Typetype, Typetarget, Stringmethod)  
  17.   {  
  18.   //省略,具體看以查看clr源代碼  
  19.   }  
  20.   publicstaticDelegateCombine(paramsDelegate[] delegates) {}  
  21.   publicstaticDelegateCombine(Delegatea, Delegateb) {}  
  22.   publicstaticDelegateRemove(Delegatesource, Delegatevalue){}  
  23.   }  
  24.   publicabstractclassMulticastDelegate: Delegate  
  25.   {  
  26.   privateObject_invocationList;  
  27.   protectedMulticastDelegate(Objecttarget, Stringmethod) : base(target, method) { }  
  28.   protectedMulticastDelegate(Typetarget, Stringmethod): base(target, method) { }  
  29.   } 

  從源代碼可以看出Delegate類提供了幾個重載的靜態方法CreateDelegate,方法返回值是Delegate類型。如果是實例方法則把對象引用傳遞給它,如是靜態方法則傳入對象類型。

  1.   publicdelegateintDelegateCaculate(inta,intb);  
  2.   publicclassCaculate  
  3.   {  
  4.   publicintAdd(intnum1, intnum2)  
  5.   {  
  6.   returnnum1 + num2;  
  7.   }  
  8.   publicstaticintSubtract(intnum1, intnum2)  
  9.   {  
  10.  returnnum2 - num1;  
  11.   }  
  12.   }  
  13.   classProgram  
  14.  {  
  15.   staticvoidMain(string[] args)  
  16.   {  
  17.   Caculatecaculate = newCaculate();  
  18.   TypetypeCaculate = typeof(Caculate);  
  19.   TypetypeDelegate = typeof(DelegateCaculate);  
  20.   DelegateCaculateadd = (DelegateCaculate)Delegate.CreateDelegate(typeDelegate, caculate, "Add");  
  21.   DelegateCaculatesubtract = (DelegateCaculate)Delegate.CreateDelegate(typeDelegate, typeCaculate, "Subtract");  
  22.   Console.WriteLine("add:"+ add(10, 20));  
  23.   Console.WriteLine("subtract:"+ subtract(10, 20));  
  24.   Console.ReadLine();  
  25.   }  
  26.   } 

  CreateDelegate需要通過遍歷元數據來獲取方法句柄。C#語法提供了更便利的方法來調用委托,可以簡單通過類型名或者對象名來限定方法,而且不需要通過遍歷元數據,C#編譯器使用底層CIL的ldftn或許ldvirtftn操作符獲取方法地址,相對來說要比CreateDelegate快的多了。上面的Main方法可以改寫為

  1.   staticvoidMain(string[] args)  
  2.   {  
  3.   DelegateCaculateadd = newDelegateCaculate(newCaculate().Add);  
  4.   DelegateCaculatesubtract = newDelegateCaculate(Caculate.Subtract);  
  5.   Console.WriteLine("add:"+ add(10, 20));  
  6.   Console.WriteLine("subtract:"+ subtract(10, 20));  
  7.   Console.ReadLine();  
  8.   } 

  可以將多個委托對象放到委托對象數組中,一旦對其調用,CLR將遍歷委托數組,對其逐一調用。

  1.   publicdelegatevoidDelegateCaculate(inta,intb);  
  2.   publicclassCaculate  
  3.   {  
  4.   publicstaticvoidAdd(intnum1, intnum2)  
  5.   {  
  6.   Console.WriteLine((num1+ num2));  
  7.   }  
  8.   publicstaticvoidSubtract(intnum1, intnum2)  
  9.   {  
  10.   Console.WriteLine((num2- num1));  
  11.   }  
  12.   }  
  13.   classProgram  
  14.   {  
  15.   staticvoidMain(string[] args)  
  16.   {  
  17.   DelegateArray(newDelegateCaculate(Caculate.Add), newDelegateCaculate(Caculate.Subtract));  
  18.   Console.ReadLine();  
  19.   }  
  20.   staticvoidDelegateArray(DelegateCaculatea, DelegateCaculateb)  
  21.   {  
  22.   DelegateCaculatedelChain = null 
  23.   delChain = (DelegateCaculate)Delegate.Combine(delChain, a);  
  24.   delChain = (DelegateCaculate)Delegate.Combine(delChain, b);  
  25.   delChain(10, 20);  
  26.   }  
  27.   } 

  C#提供了更便捷的語法把委托對象添加到委托數組內,可以這樣修改上面的DelegateArray方法,

  1.   staticvoidDelegateArray(DelegateCaculatea, DelegateCaculateb)  
  2.  {  
  3.   DelegateCaculatedelChain = null 
  4.   delChain += a;  
  5.   delChain+=b;  
  6.   delChain(10, 20);  
  7.   } 

  當執行(DelegateCaculate)Delegate.Combine(delChain, a)時,因為委托數組中只有一個a對象,所以delChain也只是簡單的指向a。示意圖如下

  當執行(DelegateCaculate)Delegate.Combine(delChain, b)是,因為委托數組已經有兩個對象了,這時會生成一個新的MulticastDelegate對象讓delChain指向它,而_invocationList指向一個委托數組對象,示意圖如下

  如果還有委托對象加入,將會再次生成一個新的MulticastDelegate對象讓delChain指向這個新對象,原來的對象則等待垃圾回收器進行回收,這點可以查看CLR源代碼,每添加一個委托對象就調用一次方法NewMulticastDelegate,這個方法返回值是MulticastDelegate。

  委托與接口

  接口與委托都擁有調用特定方法的能力,所以他們在這點很相像。但是接口需要目標方法的類型聲明必須與該接口兼容,而委托可以被任何類型調用,只要該類型的目標方法簽名和委托簽名匹配即可。

  那么何時用委托,何時用接口呢,msdn 總結的非常好,我就直接給粘貼過來了,

  委托在以下情況很有用:

  1、 調用單個方法。

  2、 一個類希望有方法規范的多個實現。

  3、 希望允許靜態方法實現規范。

  4、 希望類似事件的設計模式。

  5、 調用方不需要知道或獲得實現與委托簽名匹配的方法的對象。

  6、 實現的提供程序希望只對少數選擇組件“分發”規范實現。

  7、 需要方法的組合。

  接口在以下情況很有用:

  1、 規范定義一組相關方法。

  2、 類通常只實現規范一次。

  3、 接口的調用方希望轉換為接口類型或從接口類型轉換,以獲得其他接口或類。

原文鏈接:http://www.cnblogs.com/qiuwuyu/archive/2011/08/29/2157230.html

責任編輯:彭凡 來源: 博客園
相關推薦

2024-10-05 00:00:35

Action?C#Func?

2024-05-30 12:24:03

C#開發

2024-09-29 09:28:38

Action?C#

2009-09-08 15:28:24

C#委托

2024-04-01 11:30:57

C#拷貝

2009-08-18 10:35:26

C#委托

2009-09-07 03:23:40

C# Main方法

2009-05-26 16:33:48

PythonC#Run As

2009-08-20 18:11:08

C#異步委托

2024-05-16 13:36:04

C#委托事件

2024-05-16 12:33:37

C#編程指針

2024-04-09 08:04:42

C#結構await

2024-12-20 09:48:47

C#Python代碼

2009-08-18 10:25:41

C#委托

2009-08-18 10:54:17

C#事件和委托

2009-06-24 10:49:16

JavaScript

2009-08-03 13:23:04

C#編程組件-事件-委托

2024-05-15 09:11:51

委托事件C#

2009-08-24 16:19:42

C# 泛型方法

2009-04-10 09:55:44

C#反射.NET
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 一区二区在线免费观看 | 狠狠的操 | 亚洲精品国产偷自在线观看 | 国产一级特黄视频 | 亚州av| 精精国产视频 | 国产精品完整版 | 亚洲精品大全 | 日韩在线中文字幕 | 成人免费在线视频 | 国产精品永久久久久久久www | 亚洲精品一区中文字幕乱码 | 午夜视频网 | 日本三级电影免费 | 亚洲三级在线 | 精品亚洲一区二区三区 | 欧美一级片在线观看 | 天天久久 | 久久久久成人精品亚洲国产 | 欧美色成人 | 久久精品91 | 天天插天天操 | 国产成人精品久久二区二区 | 亚洲精品在线看 | 久久国内精品 | www.国产精 | 精品国产乱码久久久久久蜜柚 | jizz18国产 | 日本不卡免费新一二三区 | 视频一区二区三区四区五区 | 羞羞网站在线免费观看 | 国产91在线播放精品91 | 免费观看毛片 | 亚洲福利精品 | 欧美一区二区三区在线免费观看 | 久久9999久久 | 国产大学生情侣呻吟视频 | 久久精品毛片 | 国产精品视频综合 | 99热这里都是精品 | 亚洲视频中文字幕 |