一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

.NET 反射、委托技術(shù)與設(shè)計模式

 vavava 2010-07-07

.NET 反射、委托技術(shù)與設(shè)計模式

1 反射技術(shù)與設(shè)計模式 
        反射(Reflection)是.NET中的重要機制,通過放射,可以在運行時獲得.NET中每一個類型(包括類、結(jié)構(gòu)、委托、接口和枚舉等)的成員,包括方法、屬性、事件,以及構(gòu)造函數(shù)等。還可以獲得每個成員的名稱、限定符和參數(shù)等。有了反射,即可對每一個類型了如指掌。如果獲得了構(gòu)造函數(shù)的信息,即可直接創(chuàng)建對象,即使這個對象的類型在編譯時還不知道。

1.1 .NET可執(zhí)行應(yīng)用程序結(jié)構(gòu) 
        程序代碼在編譯后生成可執(zhí)行的應(yīng)用,我們首先要了解這種可執(zhí)行應(yīng)用程序的結(jié)構(gòu)。 
        應(yīng)用程序結(jié)構(gòu)分為應(yīng)用程序域—程序集—模塊—類型—成員幾個層次,公共語言運行庫加載器管理應(yīng)用程序域,這種管理包括將每個程序集加載到相應(yīng)的應(yīng)用程序域以及控制每個程序集中類型層次結(jié)構(gòu)的內(nèi)存布局。 
        程序集包含模塊,而模塊包含類型,類型又包含成員,反射則提供了封裝程序集、模塊和類型的對象。我們可以使用反射動態(tài)地創(chuàng)建類型的實例,將類型綁定到現(xiàn)有對象或從現(xiàn)有對象中獲取類型,然后調(diào)用類型的方法或訪問其字段和屬性。反射通常具有以下用途。
(1)使用Assembly定義和加載程序集,加載在程序集清單中列出模塊,以及從此程序集中查找類型并創(chuàng)建該類型的實例。
(2)使用Module了解包含模塊的程序集以及模塊中的類等,還可以獲取在模塊上定義的所有全局方法或其他特定的非全局方法。
(3)使用ConstructorInfo了解構(gòu)造函數(shù)的名稱、參數(shù)、訪問修飾符(如pulic 或private)和實現(xiàn)詳細信息(如abstract或virtual)等。使用Type的GetConstructors或 GetConstructor方法來調(diào)用特定的構(gòu)造函數(shù)。
(4)使用MethodInfo了解方法的名稱、返回類型、參數(shù)、訪問修飾符(如 pulic 或private)和實現(xiàn)詳細信息(如abstract或virtual)等。使用Type的GetMethods或GetMethod方法來調(diào)用特定的方法。
(5)使用FiedInfo了解字段的名稱、訪問修飾符(如public或private)和實現(xiàn)詳細信息(如static)等,并獲取或設(shè)置字段值。
(6)使用EventInfo了解事件的名稱、事件處理程序數(shù)據(jù)類型、自定義屬性、聲明類型和反射類型等,添加或移除事件處理程序。
(7)使用PropertyInfo了解屬性的名稱、數(shù)據(jù)類型、聲明類型、反射類型和只讀或可寫狀態(tài)等,獲取或設(shè)置屬性值。
(8)使用ParameterInfo了解參數(shù)的名稱、數(shù)據(jù)類型、是輸入?yún)?shù)還是輸出參數(shù),以及參數(shù)在方法簽名中的位置等。 
        System.Reflection.Emit命名空間的類提供了一種特殊形式的反射,可以在運行時構(gòu)造類型。 
        反射也可用于創(chuàng)建稱為類型瀏覽器的應(yīng)用程序,使用戶能夠選擇類型,然后查看有關(guān)選定類型的信息。 
        此外,Jscript等語言編譯器使用反射來構(gòu)造符號表。System.Runtime.Serialization命名空間中的類使用反射來訪問數(shù)據(jù)并確定要永久保存的字段,System.Runtime.Remoting命名空間中的類通過序列化來間接地使用反射。

1.2 反射技術(shù)示例 
        下面是反射技術(shù)的示例,我們可以在程序去得時動態(tài)實例化對象,獲得對象的屬性,并調(diào)用對象的方法。
 1Namespace ReflectionExample
 2{
 3  class Class1
 4  {
 5      [STAThread]
 6      static void Main (string [ ] args)
 7      {
 8          System.Console.WriteLine(“列出程序集中的所有類型”);
 9          Assembly a = Assembly.LoadFrom (“ReflectionExample.exe”);
10          Type[ ] mytypes = a.GetTypes( );
11
12          Foreach (Type t in mytypes)
13          {
14              System.Console.WriteLine ( t.Name );
15          }

16          System.Console.ReadLine ( );
17      System.Console.WriteLine (“列出 HellWord中的所有方法” );
18      Type ht = typeof(HelloWorld);
19      MethodInfo[] mif = ht.GetMethods();
20      foreach(MethodInfo mf in mif)
21      {
22          System.Console.WriteLine(mf.Name);
23      }

24      System.Console.ReadLine();
25      System.Console.WriteLine("實例化HelloWorld,并調(diào)用SayHello方法");
26      Object obj = Activator.CreateInstance(ht);
27      string[] s = {"zhenlei"};
28      Object bojName = Activator.CreateInstance(ht,s);
29      BindingFlags flags = (BindingFlags.NonPublic|BindingFlags.Public|BindingFlags.Static|BindingFlags.Instance|BindingFlags.DeclaredOnly);
30      MethodInfo msayhello = ht.GetMethod("SayHello");
31      msayhello.Invoke(obj,null);
32      msayhello.Invoke(objName,null);
33      System.Console.ReadLine();
34    }

35    }

36}

 1using System;
 2namespace ReflectionExample
 3{
 4    public class HelloWorld
 5    {
 6        string myName = null;
 7        public HelloWorld(string name)
 8        {
 9            myName = name;
10        }

11        public HelloWorld() : this(null)
12        {}
13        public string Name
14        {
15            get
16            {
17                return myName;
18            }

19        }

20        public void SayHello()
21        {
22            if(myName == null)
23            {
24                System.Console.WriteLine("Hello World");
25            }

26            else
27            {
28                System.Console.WriteLine("Hello," + myName);
29            }

30        }

31    }

32}

33

1.3 在設(shè)計模式實現(xiàn)中使用反射技術(shù) 
        采用反射技術(shù)可以簡化工廠的實現(xiàn)。
(1)工廠方法:通過反射可以將需要實現(xiàn)的子類名稱傳遞給工廠方法,這樣無須在子類中實現(xiàn)類的實例化。
(2)抽象工廠:使用反射可以減少抽象工廠的子類。 
        采用反射技術(shù)可以簡化工廠代碼的復(fù)雜程度,在.NET項目中,采用反射技術(shù)的工廠已經(jīng)基本代替了工廠方法。 
        采用反射技術(shù)可以極大地簡化對象的生成,對以下設(shè)計模式的實現(xiàn)也有很大影響。
(1)命令模式:可以采用命令的類型名稱作為參數(shù)直接獲得命令的實例,并且可以動態(tài)執(zhí)行命令。
(2)享元模式:采用反射技術(shù)實例化享元可以簡化享元工廠。

2 委托技術(shù)與設(shè)計模式
        委托技術(shù)是.NET引入的一種重要技術(shù),使用委托可以實現(xiàn)對象行為的動態(tài)綁定,從而提高設(shè)計的靈活性。

2.1 .NET中的委托技術(shù)
        .NET運行庫支持稱為“委托”的引用類型,其作用類似于C++中的函數(shù)指針。與函數(shù)指針不同,委托實例獨立于其封裝方法的類,主要是那些方法與委托類型兼容。另外,函數(shù)指針只能引用靜態(tài)函數(shù),而委托可以引用靜態(tài)和實例方法。委托主要用于.NET Framework中的事件處理程序和回調(diào)函數(shù)。
        所有委托都從System.Delegate繼承而來并且有一個調(diào)用列表,這是在調(diào)用委托時所執(zhí)行方法的一個鏈接列表。產(chǎn)生的委托可以用匹配的簽名引用任何方法,沒有為具有返回類型并在調(diào)用列表中包含多個方法的委托定義返回值。
        可以使用的委托Cimbine及Remove方法在其調(diào)用列表中添加和移除方法。若要調(diào)用委托,可使用Invoke方法,或者使用BeginInvoke 和EndInvoke方法異步調(diào)用委托。委托類的實現(xiàn)由運行庫提供,而不由用戶代碼提供。
        委托適用于那種在某些語言中需要用函數(shù)指針來解決的情況,但是與函數(shù)指針不同,它是面向?qū)ο蠛皖愋桶踩摹?br>        委托聲明定義一個類,它是從System.Delegate類派生的類。委托實例封裝了一個調(diào)用列表,其中列出了一個或多個方法,每個方法稱為一個可調(diào)用實體。對于實例方法,可調(diào)用實體由一個實例和該實例的方法組成;對于靜態(tài)方法,可調(diào)用實體僅由一個方法組成。如果用一組合適的參數(shù)來調(diào)用一個委托實例,則該委托實例所封裝的每個可調(diào)用實體都會被調(diào)用,并且使用上述同一組參數(shù)。
        委托實例的一個有用的屬性是它既不知道,也不關(guān)心其封裝方法所屬類的詳細信息,對它來說最重要的是這些方法與該委托的類型兼容。即只要方法的返回類型和參數(shù)表是相同的,則方法與委托類型兼容,方法的名稱不一定要與委托類相同。
定義和使用委托分為聲明、實例化和調(diào)用3個步驟。委托用委托聲明語法聲明,如:
    delegate void myDelegate( );
聲明一個名為myDelegate的委托,它不帶參數(shù)并且不返回任何結(jié)果,如:
class Test
{
       static void F( ) 
      {
              System.Console.WriteLine (“Test.F”);
      }
       static void Main ( )  
      {
            myeDelegate d = new myDelegate (F);
            d ( );
      }
}
創(chuàng)建一個myDelegate實例,然后立即調(diào)用它。這樣做并沒有太大的意義,因為直接調(diào)用方法會更簡單。當(dāng)涉及其匿名特性時,委托才能真正顯示出其效果,如:
    void MultiCall (myDelegate d, int count )  {
      for  (int I = 0; I < count; I++)  {
        d( );
      }
    }
顯示一個重復(fù)調(diào)用 myDelegate的MultiCall 方法,這個方法不知道,也不必知道m(xù)yDelegate的目標方法的類型、該方法具有的可訪問性或者是否為靜態(tài)。對它來說最重要的是目標方法與 myDelegate兼容。

2.2示例
        下面的例子說明了委托的實現(xiàn),代碼如下:
 1using System;
 2namespace DelegateExample
 3{
 4    public class TemplateMethod
 5    {
 6        public delegate float Comp(float a,float b);
 7        public Comp myComp;
 8        public TemplateMethod()
 9        {}
10        public float DoComp(float[] f)
11        {
12            float nf = float.NaN;
13            foreach(float df in f)
14            {
15                if(float.IsNaN(nf))
16                    nf = df;
17                else
18                    nf = myComp(nf,df);
19            }

20            return nf;
21        }

22
23    }

24}

2.3 委托技術(shù)與GOF設(shè)計模式中委托的關(guān)系
        需要指出的是,.NET中的委托技術(shù)與GOF在《設(shè)計模式》中所提列的委托的意圖一致,但在實現(xiàn)方法上有相當(dāng)大的區(qū)別。.NET中的委托更進一步地降低了對象間的耦合性,將靜態(tài)的組合關(guān)系變?yōu)檫\行時的動態(tài)組合關(guān)系。
        GOF在《設(shè)計模式》中定義的委托是:“委托是一種組合方法,它使組合具有與繼承同樣的復(fù)用能力。在委托方式下,有兩個對象參與處理一個請求,接受請求的對象將操作委托給它的代理者(delegate),它類似于子類將請求交給它的父類處理。使用繼承時,被繼承的操作總能引用接受請求的對象。在C++中通過this成員變量,在Smalltalk中則通過self。委托方式為了得到同樣的效果,接受請求的對象將自身傳給被委托者(代理人),使被委托的操作可以引用接受請求的對象。”
        如果采用.NET的委托技術(shù),上述結(jié)構(gòu)可以更加靈活。Window不引用Rectangle即可實現(xiàn)Area的計算,為此首先聲明一個計算面積的委托定義,示例代碼如下:
    public delegate float Darea();
然而在Window類中聲明與這個代理一致的接口:
    class Window
    { 
        public Darea Area;
    }
這里不需要引用Rectangle類,只是在執(zhí)行時動態(tài)綁定即可:
Rectangle rc = new Rectangle();
Window w = new Window();
w.Area = new Darea(rc.Area);
        這樣當(dāng)調(diào)用w的Area時,實際調(diào)用的是Reactangel的Area方法。從實現(xiàn)意圖上看,.NET的委托更好地實現(xiàn)了GOF所闡述的意圖,結(jié)構(gòu)上也更為靈活。但這兩種委托解決的不是一個層面的問題,GOF的委托強調(diào)的是一種策略,而.NET和委托技術(shù)則是具體實現(xiàn)。

2.4 委托技術(shù)與設(shè)計模式實現(xiàn)
        采用委托技術(shù)可以進一步實現(xiàn)用組合代替繼承的思路,很多采用繼承實現(xiàn)的關(guān)系可以采用委托實現(xiàn)。采用委托可以簡化下列設(shè)計模式的使用。
(1)模板方法:這種方法采用繼承實現(xiàn)具體方法,采用委托可以動態(tài)實現(xiàn)方法的組合。
(2)觀察者:可以使用事件委托實現(xiàn)觀察者與主題之間的通信。
(3)中介者:使用委托可以去除工件與中介者之間的耦合關(guān)系。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    国内外激情免费在线视频| 极品少妇一区二区三区精品视频 | 日韩欧美国产三级在线观看| 中文字幕久热精品视频在线 | 亚洲欧美中文日韩综合| 国产在线不卡中文字幕| 日韩欧美91在线视频| 国产欧美性成人精品午夜| 视频一区日韩经典中文字幕| 五月婷婷综合激情啪啪| 精品欧美一区二区三久久| 中文字幕日韩欧美亚洲午夜| 91亚洲国产日韩在线| 亚洲妇女作爱一区二区三区| 欧美精品久久一二三区| 免费播放一区二区三区四区 | 日韩欧美一区二区不卡看片| 久久福利视频这里有精品| 中文字幕人妻av不卡| 成人国产激情在线视频| 国产不卡最新在线视频| 欧美日韩国产一级91| 日韩少妇人妻中文字幕| 欧美性高清一区二区三区视频| 夜色福利久久精品福利| 欧洲偷拍视频中文字幕| 成年人黄片大全在线观看| 99久久国产精品亚洲| 久久国产精品熟女一区二区三区 | 日本黄色高清视频久久| 亚洲一区二区三区精选| 国产在线视频好看不卡| 日本精品中文字幕人妻| 欧洲亚洲精品自拍偷拍| 国产肥妇一区二区熟女精品| 亚洲夫妻性生活免费视频| 亚洲中文字幕乱码亚洲| 中国一区二区三区人妻| 高清免费在线不卡视频| 亚洲中文字幕在线乱码av| 一区二区三区四区亚洲另类|