<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      [你必須知道的.NET] 第三回:歷史糾葛:特性和屬性

      發布日期:2007.4.19 作者:Anytao

      ?2007 Anytao.com 轉貼請注明出處,留此信息。

      本文將介紹以下內容:

      ? 定制特性的基本概念和用法

      ? 屬性與特性的區別比較

      ? 反射的簡單介紹

      1. 引言

      attribute是.NET框架引入的有一技術亮點,因此我們有必要花點時間來了解本文的內容,走進一個發現attribute登堂入室的入口。因為.NET Framework中使用了大量的定制特性來完成代碼約定,[Serializable]、[Flags]、[DllImport]、[AttributeUsage]這些的構造,相信我們都見過吧,那么你是否了解其背后的技術。

      提起特性,由于高級語言發展的歷史原因,不免讓人想起另一個耳熟能詳的名字:屬性。特性和屬性,往往給初學者或者從C++轉移到C#的人混淆的概念沖擊。那么,什么是屬性,什么是特性,二者的概念和區別,用法與示例,將在本文做以概括性的總結和比較,希望給你的理解帶來收獲。另外本文的主題以特性的介紹為主,屬性的論述重點突出在二者的比較上,關于屬性的更多論述將在另一篇主題中詳細討論,敬請關注。

      2. 概念引入

      2.1. 什么是特性?

      MADN的定義為:公共語言運行時允許添加類似關鍵字的描述聲明,叫做attributes, 它對程序中的元素進行標注,如類型、字段、方法和屬性等。Attributes和Microsoft .NET Framework文件的元數據保存在一起,可以用來向運行時描述你的代碼,或者在程序運行的時候影響應用程序的行為。

      我們簡單的總結為:定制特性attribute,本質上是一個類,其為目標元素提供關聯附加信息,并在運行期以反射的方式來獲取附加信息。具體的特性實現方法,在接下來的討論中繼續深入。

      2.2. 什么是屬性?

       屬性是面向對象編程的基本概念,提供了對私有字段的訪問封裝,在C#中以get和set訪問器方法實現對可讀可寫屬性的操作,提供了安全和靈活的數據訪問封裝。關于屬性的概念,不是本文的重點,而且相信大部分的技術人員應該對屬性有清晰的概念。以下是簡單的屬性示例:

       

          public class MyProperty
          {
              
      //定義字段
              private string _name;
              
      private int _age;

              
      //定義屬性,實現對_name字段的封裝
              public string Name
              {
                  
      get { return (_name == null? string.Empty : _name; }
                  
      set { _name = value; }
              }

              
      //定義屬性,實現對_age字段的封裝
              
      //加入對字段的范圍控制
              public int Age
              {
                  
      get { return _age; }
                  
      set
                  {
                      
      if ((value > 0&& (value < 150))
                      {
                          _age 
      = value;
                      }
                      
      else
                      {
                          
      throw new Exception("Not a real age");
                      }
                  }
              }
          }

          
      public class MyTest
          {
              
      public static void Main(string[] args)
              {
                  MyProperty myProperty 
      = new MyProperty();
                  
      //觸發set訪問器
                  myProperty.Name = "Anytao";
                  
      //觸發get訪問器
                  Console.WriteLine(myProperty.Name);
                  myProperty.Age 
      = 66;
                  Console.WriteLine(myProperty.Age.ToString());
                  Console.ReadLine();
              }
          }

       


      2.3. 區別與比較

      通過對概念的澄清和歷史的回溯,我們知道特性和屬性只是在名稱上有過糾葛,在MSDN上關于attribute的中文解釋甚至還是屬性,但是我同意更通常的稱呼:特性。在功能上和應用上,二者其實沒有太多模糊的概念交叉,因此也沒有必要來比較其應用的異同點。本文則以特性的概念為重點,來討論其應用的場合和規則。

      我理解的定制特性,就是為目標元素,可以是數據集、模塊、類、屬性、方法、甚至函數參數等加入附加信息,類似于注釋,但是可以在運行期以反射的方式獲得。定制特性主要應用在序列化、編譯器指令、設計模式等方面。

      3. 通用規則

      1. 定制特性可以應用的目標元素可以為:程序集(assembly)、模塊(module)、類型(type)、屬性(property)、事件(event)、字段(field)、方法(method)、參數(param)、返回值(return),應該全了。
      2. 定制特性以[,]形式展現,放在緊挨著的元素上,多個特性可以應用于同一元素,特性間以逗號隔開,以下表達規則有效:[AttributeUsage][ Flags]、[AttributeUsage, Flags]、[Flags, AttibuteUsageAttribute]、[AttributeUsage(), FlagesAttribute()]
      3. attibute實例,是在編譯期進行初始化,而不是運行期。
      4. C#允許以指定的前綴來表示特性所應用的目標元素,建議這樣來處理,因為顯式處理可以消除可能帶來的二義性。例如:  
        using System; 

        namespace Anytao.net 
        {
            [assembly: MyAttribute(
        1)]          //應用于程序集
            [moduel: MyAttribute(2)]            //應用于模塊
            pubic class Attribute_how2do
            {
                
        //
            } 
        }

         

      5. 定制特性類型,必須直接或者間接的繼承自System.Attribute類,而且該類型必須有公有構造函數來創建其實例。
      6. 所有自定義的特性名稱都應該有個Attribute后綴,這是習慣性約定。
      7. 定制特性也可以應用在其他定制特性上,這點也很好理解,因為定制特性本身也是一個類,遵守類的公有規則。例如很多時候我們的自定義定制特性會應用AttributeUsageAttribute特性,來控制如何應用新定義的特性。  
        [AttributeUsageAttribute(AttributeTarget.All),
        AllowMultiple 
        = true
        Inherited 
        = true]
        class MyNewAttribute: System.Attribute
        {
        //

         

      8. 定制特性不會影響應用元素的任何功能,只是約定了該元素具有的特質。
      9. 所有非抽象特性必須具有public訪問限制。
      10. 特性常用于編譯器指令,突破#define, #undefine, #if, #endif的限制,而且更加靈活。
      11. 定制特性常用于在運行期獲得代碼注釋信息,以附加信息來優化調試。
      12. 定制特性可以應用在某些設計模式中,如工廠模式。
      13. 定制特性還常用于位標記,非托管函數標記、方法廢棄標記等其他方面。

      4. 特性的應用

      4.1. 常用特性

      常用特性,也就是.NET已經提供的固有特性,事實上在.NET框架中已經提供了豐富的固有特性由我們發揮,以下精選出我認為最常用、最典型的固有特性做以簡單討論,當然這只是我的一家之言,亦不足道。我想了解特性,還是從這里做為起點,從.NET提供的經典開始,或許是一種求知的捷徑,希望能給大家以啟示。

      1. AttributeUsage

        AttributeUsage特性用于控制如何應用自定義特性到目標元素。關于AttributeTargetsAllowMultipleInheritedValidOn,請參閱示例說明和其他文檔。我們已經做了相當的介紹和示例說明,我們還是在實踐中自己體會更多吧。

      2. Flags

        以Flags特性來將枚舉數值看作位標記,而非單獨的數值,例如: 

        enum Animal
        {
            Dog     
        = 0x0001,
            Cat     
        = 0x0002,
            Duck    
        = 0x0004,
          Chicken 
        = 0x0008
        }

        因此,以下實現就相當輕松, 

        Animal animals = Animal.Dog | Animal.Cat;
        Console.WriteLine(animals.ToString());

        請猜測結果是什么,答案是:"Dog, Cat"。如果沒有Flags特別,這里的結果將是"3"。關于位標記,也將在本系列的后續章回中有所交代,在此只做以探討止步。

      3. DllImport

        DllImport特性,可以讓我們調用非托管代碼,所以我們可以使用DllImport特性引入對Win32 API函數的調用,對于習慣了非托管代碼的程序員來說,這一特性無疑是救命的稻草。 

        using System;
        using System.Runtime.InteropServices;

        namespace Anytao.net
        {
            
        class MainClass 
            {
               [DllImport(
        "User32.dll")]
               
        public static extern int MessageBox(int hParent, string msg, string caption, int type);

               
        static int Main() 
               {
                  
        return MessageBox(0"How to use attribute in .NET""Anytao_net"0);
              }
            }
        }
      4. Serializable

        Serializable特性表明了應用的元素可以被序列化(serializated),序列化和反序列化是另一個可以深入討論的話題,在此我們只是提出概念,深入的研究有待以專門的主題來呈現,限于篇幅,此不贅述。

      5. Conditional

        Conditional特性,用于條件編譯,在調試時使用。注意:Conditional不可應用于數據成員和屬性。

      還有其他的重要特性,包括:DescriptionDefaultValueCategoryReadOnlyBrowerAble等,有時間可以深入研究。

      4.2. 自定義特性

      既然attribute,本質上就是一個類,那么我們就可以自定義更特定的attribute來滿足個性化要求,只要遵守上述的12條規則,實現一個自定義特性其實是很容易的,典型的實現方法為:

      1. 定義特性  

         

            [AttributeUsage(AttributeTargets.Class |
                AttributeTargets.Method,
                Inherited 
        = true)]
            
        public class TestAttribute : System.Attribute
            {
                
        public TestAttribute(string message)
                {
                    Console.WriteLine(message);
                }
                
        public void RunTest()
                {
                    Console.WriteLine(
        "TestAttribute here.");
                }
            }

         

      2. 應用目標元素  
                [Test("Error Here.")]
                
        public void CannotRun()
                {
                    
        //
                }

         

      3. 獲取元素附加信息

        如果沒有什么機制來在運行期來獲取Attribute的附加信息,那么attribute就沒有什么存在的意義。因此,.NET中以反射機制來實現在運行期獲取attribute信息,實現方法如下:  

         

         

                public static void Main()
                {
                    Tester t 
        = new Tester();
                    t.CannotRun();

                    Type tp 
        = typeof(Tester);
                    MethodInfo mInfo 
        = tp.GetMethod("CannotRun");            
                    TestAttribute myAtt 
        = (TestAttribute)Attribute.GetCustomAttribute(mInfo, typeof(TestAttribute));
                    myAtt.RunTest();
                }

         

      5. 經典示例

      5.1 小菜一碟

      啥也不說了,看注釋吧。

      using System;
      using System.Reflection;                                 //應用反射技術獲得特性信息

      namespace Anytao.net
      {
          
      //定制特性也可以應用在其他定制特性上,
          
      //應用AttributeUsage,來控制如何應用新定義的特性
          [AttributeUsageAttribute(AttributeTargets.All,       //可應用任何元素
              AllowMultiple = true,                            //允許應用多次
              Inherited = false)]                              //不繼承到派生類
          
      //特性也是一個類,
          
      //必須繼承自System.Attribute類,
          
      //命名規范為:"類名"+Attribute。        
          public class MyselfAttribute : System.Attribute
          {
              
      //定義字段
              private string _name;
              
      private int _age;
              
      private string _memo;

              
      //必須定義其構造函數,如果不定義有編譯器提供無參默認構造函數
              public MyselfAttribute()
              {
              }
              
      public MyselfAttribute(string name, int age)
              {
                  _name 
      = name;
                  _age 
      = age;
              }

              
      //定義屬性
              
      //顯然特性和屬性不是一回事兒
              public string Name
              {
                  
      get { return _name == null ? string.Empty : _name; }
              }

              
      public int Age
              {
                  
      get { return _age; }
              }

              
      public string Memo
              {
                  
      get { return _memo; }
                  
      set { _memo = value; }
              }

              
      //定義方法
              public void ShowName()
              {
                  Console.WriteLine(
      "Hello, {0}", _name == null ? "world." : _name);
              }
          }

          
      //應用自定義特性
          
      //可以以Myself或者MyselfAttribute作為特性名
          
      //可以給屬性Memo賦值
          [Myself("Emma"25, Memo = "Emma is my good girl.")]
          
      public class Mytest
          {
              
      public void SayHello()
              {
                  Console.WriteLine(
      "Hello, my.net world.");
              }
          }

          
      public class Myrun
          {
              
      public static void Main(string[] args)
              {
                  
      //如何以反射確定特性信息
                  Type tp = typeof(Mytest);
                  MemberInfo info 
      = tp;
                  MyselfAttribute myAttribute 
      =
                      (MyselfAttribute)Attribute.GetCustomAttribute(info, 
      typeof(MyselfAttribute));
                  
      if (myAttribute != null)
                  {
                      
      //嘿嘿,在運行時查看注釋內容,是不是很爽
                      Console.WriteLine("Name: {0}", myAttribute.Name);
                      Console.WriteLine(
      "Age: {0}", myAttribute.Age);
                      Console.WriteLine(
      "Memo of {0} is {1}", myAttribute.Name, myAttribute.Memo);
                      myAttribute.ShowName();
                  }

                  
      //多點反射
                  object obj = Activator.CreateInstance(typeof(Mytest));

                  MethodInfo mi 
      = tp.GetMethod("SayHello");
                  mi.Invoke(obj, 
      null);
                  Console.ReadLine();
              }
          }
      }

       啥也別想了,自己做一下試試。

      5.2 他山之石

      6. 結論

       Attribute是.NET引入的一大特色技術,但在博客園中討論的不是很多,所以拿出自己的體會來分享,希望就這一技術要點進行一番登堂入室的引導。更深層次的應用,例如序列化、程序安全性、設計模式多方面都可以挖掘出閃耀的金子,這就是.NET在技術領域帶來的百變魅力吧。希望大家暢所欲言,來完善和補充作者在這方面的不全面和認知上的不深入,那將是作者最大的鼓勵和動力。
       

      參考文獻

      (USA)Stanley B.Lippman, C# Primer 

      溫故知新

      [開篇有益]

      [第一回:恩怨情仇:is和as]

      [第二回:對抽象編程:接口和抽象類

      ?2007 Anytao.com 轉貼請注明出處,留此信息。

      本貼子以現狀提供且沒有任何擔保,同時也沒有授予任何權利。
      This posting is provided "AS IS" with no warranties, and confers no rights.

      posted @ 2007-04-19 01:53  Anytao  閱讀(25934)  評論(65)    收藏  舉報
      主站蜘蛛池模板: 国产无遮挡又黄又大又爽| av大片在线无码免费| 又黄又刺激又黄又舒服| 精品国产亚洲一区二区三区| 4虎四虎永久在线精品免费| 在线日韩日本国产亚洲| 精品一区二区成人码动漫| 男女扒开双腿猛进入爽爽免费看| 少妇高潮喷水正在播放| 国产精品成人免费视频网站京东| 国产香蕉一区二区三区在线视频| 欧洲人妻丰满av无码久久不卡| 日韩精品 在线 国产 丝袜| 一区二区三区四区自拍偷拍 | 欧美肥老太牲交大战| 2020国产成人精品视频| 免费a级毛片18以上观看精品| 91中文字幕一区在线| 国产人妻精品午夜福利免费| 国产999久久高清免费观看| 精品乱码一区二区三四五区| 国产av黄色一区二区三区| 国产360激情盗摄全集| 亚洲爆乳少妇无码激情| 国产在线午夜不卡精品影院| 少妇高潮惨叫喷水在线观看| 成人动漫在线观看| 护士张开腿被奷日出白浆| 忘忧草日本在线播放www| 亚洲 欧美 中文 日韩aⅴ| 丰满少妇内射一区| 国产精品欧美福利久久| 日韩人妻无码一区二区三区俄罗斯| 亚洲夂夂婷婷色拍ww47| 国产精品久久久久av福利动漫| 精品乱人码一区二区二区| 日韩在线视频线观看一区| 亚洲精品免费一二三区| 日韩高清不卡一区二区三区| 亚洲国产精品日韩在线| 少妇高潮喷水正在播放|