• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
    • 軟件測試技術
    • 軟件測試博客
    • 軟件測試視頻
    • 開源軟件測試技術
    • 軟件測試論壇
    • 軟件測試沙龍
    • 軟件測試資料下載
    • 軟件測試雜志
    • 軟件測試人才招聘
      暫時沒有公告

    字號: | 推薦給好友 上一篇 | 下一篇

    .NET反射、委托技術與設計模式

    發布: 2007-6-14 17:26 | 作者: 網絡轉載 | 來源: 網絡 | 查看: 67次 | 進入軟件測試論壇討論

    領測軟件測試網

    1 反射技術與設計模式

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

    1.1 .NET可執行應用程序結構

     程序代碼在編譯后生成可執行的應用,我們首先要了解這種可執行應用程序的結構。

     應用程序結構分為應用程序域—程序集—模塊—類型—成員幾個層次,公共語言運行庫加載器管理應用程序域,這種管理包括將每個程序集加載到相應的應用程序域以及控制每個程序集中類型層次結構的內存布局。

     程序集包含模塊,而模塊包含類型,類型又包含成員,反射則提供了封裝程序集、模塊和類型的對象。我們可以使用反射動態地創建類型的實例,將類型綁定到現有對象或從現有對象中獲取類型,然后調用類型的方法或訪問其字段和屬性。反射通常具有以下用途。

    。1)使用Assembly定義和加載程序集,加載在程序集清單中列出模塊,以及從此程序集中查找類型并創建該類型的實例。
    。2)使用Module了解包含模塊的程序集以及模塊中的類等,還可以獲取在模塊上定義的所有全局方法或其他特定的非全局方法。
    。3)使用ConstructorInfo了解構造函數的名稱、參數、訪問修飾符(如pulic 或private)和實現詳細信息(如abstract或virtual)等。使用Type的GetConstructors或GetConstructor方法來調用特定的構造函數。
    。4)使用MethodInfo了解方法的名稱、返回類型、參數、訪問修飾符(如pulic 或private)和實現詳細信息(如abstract或virtual)等。使用Type的GetMethods或GetMethod方法來調用特定的方法。
    。5)使用FiedInfo了解字段的名稱、訪問修飾符(如public或private)和實現詳細信息(如static)等,并獲取或設置字段值。
    。6)使用EventInfo了解事件的名稱、事件處理程序數據類型、自定義屬性、聲明類型和反射類型等,添加或移除事件處理程序。
    。7)使用PropertyInfo了解屬性的名稱、數據類型、聲明類型、反射類型和只讀或可寫狀態等,獲取或設置屬性值。
    。8)使用ParameterInfo了解參數的名稱、數據類型、是輸入參數還是輸出參數,以及參數在方法簽名中的位置等。

     System.Reflection.Emit命名空間的類提供了一種特殊形式的反射,可以在運行時構造類型。
     反射也可用于創建稱為類型瀏覽器的應用程序,使用戶能夠選擇類型,然后查看有關選定類型的信息。
     此外,Jscript等語言編譯器使用反射來構造符號表。System.Runtime.Serialization命名空間中的類使用反射來訪問數據并確定要永久保存的字段,System.Runtime.Remoting命名空間中的類通過序列化來間接地使用反射。

    1.2 反射技術示例

     下面是反射技術的示例,我們可以在程序去得時動態實例化對象,獲得對象的屬性,并調用對象的方法。

    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,并調用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 在設計模式實現中使用反射技術

     采用反射技術可以簡化工廠的實現。
    。1)工廠方法:通過反射可以將需要實現的子類名稱傳遞給工廠方法,這樣無須在子類中實現類的實例化。
    。2)抽象工廠:使用反射可以減少抽象工廠的子類。

     采用反射技術可以簡化工廠代碼的復雜程度,在.NET項目中,采用反射技術的工廠已經基本代替了工廠方法。

     采用反射技術可以極大地簡化對象的生成,對以下設計模式的實現也有很大影響。
    。1)命令模式:可以采用命令的類型名稱作為參數直接獲得命令的實例,并且可以動態執行命令。
    。2)享元模式:采用反射技術實例化享元可以簡化享元工廠。

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

    2.1 .NET中的委托技術
     .NET運行庫支持稱為“委托”的引用類型,其作用類似于C++中的函數指針。與函數指針不同,委托實例獨立于其封裝方法的類,主要是那些方法與委托類型兼容。另外,函數指針只能引用靜態函數,而委托可以引用靜態和實例方法。委托主要用于.NET Framework中的事件處理程序和回調函數。

     所有委托都從System.Delegate繼承而來并且有一個調用列表,這是在調用委托時所執行方法的一個鏈接列表。產生的委托可以用匹配的簽名引用任何方法,沒有為具有返回類型并在調用列表中包含多個方法的委托定義返回值。

     可以使用的委托Cimbine及Remove方法在其調用列表中添加和移除方法。若要調用委托,可使用Invoke方法,或者使用BeginInvoke和EndInvoke方法異步調用委托。委托類的實現由運行庫提供,而不由用戶代碼提供。

     委托適用于那種在某些語言中需要用函數指針來解決的情況,但是與函數指針不同,它是面向對象和類型安全的。

     委托聲明定義一個類,它是從System.Delegate類派生的類。委托實例封裝了一個調用列表,其中列出了一個或多個方法,每個方法稱為一個可調用實體。對于實例方法,可調用實體由一個實例和該實例的方法組成;對于靜態方法,可調用實體僅由一個方法組成。如果用一組合適的參數來調用一個委托實例,則該委托實例所封裝的每個可調用實體都會被調用,并且使用上述同一組參數。

     委托實例的一個有用的屬性是它既不知道,也不關心其封裝方法所屬類的詳細信息,對它來說最重要的是這些方法與該委托的類型兼容。即只要方法的返回類型和參數表是相同的,則方法與委托類型兼容,方法的名稱不一定要與委托類相同。

     定義和使用委托分為聲明、實例化和調用3個步驟。委托用委托聲明語法聲明,如:

    delegate void myDelegate( );

    聲明一個名為myDelegate的委托,它不帶參數并且不返回任何結果,如:

    class Test
    {
    static void F( )
    {
    System.Console.WriteLine (“Test.F”);
    }
    static void Main ( )
    {
    myeDelegate d = new myDelegate (F);
    d ( );
    }
    }

    創建一個myDelegate實例,然后立即調用它。這樣做并沒有太大的意義,因為直接調用方法會更簡單。當涉及其匿名特性時,委托才能真正顯示出其效果,如:

    void MultiCall (myDelegate d, int count ) {
    for (int I = 0; I < count; I++) {
    d( );
    }
    }

    顯示一個重復調用 myDelegate的MultiCall 方法,這個方法不知道,也不必知道myDelegate的目標方法的類型、該方法具有的可訪問性或者是否為靜態。對它來說最重要的是目標方法與myDelegate兼容。

    2.2示例
     下面的例子說明了委托的實現,代碼如下:

    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 委托技術與GOF設計模式中委托的關系
     需要指出的是,.NET中的委托技術與GOF在《設計模式》中所提列的委托的意圖一致,但在實現方法上有相當大的區別。.NET中的委托更進一步地降低了對象間的耦合性,將靜態的組合關系變為運行時的動態組合關系。

     GOF在《設計模式》中定義的委托是:“委托是一種組合方法,它使組合具有與繼承同樣的復用能力。在委托方式下,有兩個對象參與處理一個請求,接受請求的對象將操作委托給它的代理者(delegate),它類似于子類將請求交給它的父類處理。使用繼承時,被繼承的操作總能引用接受請求的對象。在C++中通過this成員變量,在Smalltalk中則通過self。委托方式為了得到同樣的效果,接受請求的對象將自身傳給被委托者(代理人),使被委托的操作可以引用接受請求的對象!

     如果采用.NET的委托技術,上述結構可以更加靈活。Window不引用Rectangle即可實現Area的計算,為此首先聲明一個計算面積的委托定義,示例代碼如下:

    public delegate float Darea();

    然而在Window類中聲明與這個代理一致的接口:

    class Window
    {
    public Darea Area;
    }
    這里不需要引用Rectangle類,只是在執行時動態綁定即可:
    Rectangle rc = new Rectangle();
    Window w = new Window();
    w.Area = new Darea(rc.Area);

    這樣當調用w的Area時,實際調用的是Reactangel的Area方法。從實現意圖上看,.NET的委托更好地實現了GOF所闡述的意圖,結構上也更為靈活。但這兩種委托解決的不是一個層面的問題,GOF的委托強調的是一種策略,而.NET和委托技術則是具體實現。

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

    延伸閱讀

    文章來源于領測軟件測試網 http://www.kjueaiud.com/

    TAG: 技術 模式 設計


    關于領測軟件測試網 | 領測軟件測試網合作伙伴 | 廣告服務 | 投稿指南 | 聯系我們 | 網站地圖 | 友情鏈接
    版權所有(C) 2003-2010 TestAge(領測軟件測試網)|領測國際科技(北京)有限公司|軟件測試工程師培訓網 All Rights Reserved
    北京市海淀區中關村南大街9號北京理工科技大廈1402室 京ICP備10010545號-5
    技術支持和業務聯系:info@testage.com.cn 電話:010-51297073

    軟件測試 | 領測國際ISTQBISTQB官網TMMiTMMi認證國際軟件測試工程師認證領測軟件測試網

    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>