[C#] 只是想簡單說下特性 - Attribute

来源:http://www.cnblogs.com/liqingwen/archive/2016/09/28/5911289.html
-Advertisement-
Play Games

只是想簡單說下特性 - Attribute 【博主】反骨仔 【原文地址】http://www.cnblogs.com/liqingwen/p/5911289.html 目錄 特性簡介 使用特性 特性的參數 特性的目標 特性的常見用途 創建自定義的特性 使用反射訪問特性 特性簡介 使用特性 特性的參數 ...


只是想簡單說下特性 - Attribute

【博主】反骨仔    【原文地址】http://www.cnblogs.com/liqingwen/p/5911289.html

目錄

 

一、特性簡介

  特性提供功能強大的方法,用以將元數據或聲明信息與代碼(程式集、類型、方法、屬性等)相關聯。特性與程式實體關聯後,可在運行時使用“反射”查詢特性。

  特性具有以下屬性:

    (1)特性可向程式中添加元數據。元數據是有關在程式中定義的類型的信息。所有的 .NET 程式集都包含指定的一組元數據,這些元數據描述在程式集中定義的類型和類型成員。可以添加自定義特性,以指定所需的任何附加信息。

    (2)可以將一個或多個特性應用到整個程式集、模塊或較小的程式元素(如類和屬性)。

    (3)特性可以與方法和屬性相同的方式接受參數。

    (4)程式可以使用反射檢查自己的元數據或其他程式內的元數據。

 

二、使用特性

  特性可以放置在幾乎所有的聲明中(但特定的特性可能限制在其上有效的聲明類型)。在 C# 中,特性的指定方法為:將括在方括弧中的特性名置於其應用到的實體的聲明上方。它必須位於所應用於的元素的緊前面並與該元素在同一行。

 1     [Serializable]  //使用特性 SerializableAttribute
 2     internal class MyClass
 3     {
 4         [DllImport("user32.dll")]   //使用特性 DllImportAttribute
 5         private static extern void Do();
 6 
 7         #region 一個聲明上可放置多個特性
 8 
 9         private void MethodA([In][Out]ref double n) { }
10         private void MethodB([In, Out]ref double n) { }
11 
12         #endregion 一個聲明上可放置多個特性
13 
14         #region 某些特性對於給定實體可以指定多次
15 
16         [Conditional("DEBUG"), Conditional("TEST1")]
17         private void TraceMethod() { }
18 
19         #endregion 某些特性對於給定實體可以指定多次
20     }

  【註意】根據約定,所有特性名稱都以單詞“Attribute”結束,以便將它們與“.NET Framework”中的其他項區分。但是,在代碼中使用特性時,不需要指定 attribute 尾碼。

 

三、特性的參數

  許多特性都有參數,而這些參數可以是定位參數未命名參數命名參數。任何定位參數都必須按特定順序指定並且不能省略,而命名參數是可選的且可以按任意順序指定。首先指定定位參數。例如,這三個特性是等效的:

1 [DllImport("user32.dll")] 
2 [DllImport("user32.dll", SetLastError=false, ExactSpelling=false)] 

  第一個參數(DLL 名稱)是定位參數並且總是第一個出現,其他參數為命名參數。在這種情況下,兩個命名參數均預設為 false,因此可將其省略。

 

四、特性的目標

  特性的目標是應用該特性的實體。例如,特性可以應用於類、特定方法或整個程式集。預設情況下,特性應用於它後面的元素。但是,您也可以顯式標識要將特性應用於方法還是它的參數或返回值。

  若要顯式標識特性目標,語法:

[target : attribute-list]

 

特性目標
C# 適用對象
assembly 整個程式集
module 當前程式集模塊
field 在類或結構中的欄位
event event
method 方法或 get 和 set 屬性訪問器
param 方法參數或 set 屬性訪問器參數
property 屬性
return 方法、屬性索引器或 get 屬性訪問器的返回值
type 結構、類、介面、枚舉或委托

 

//示例:將特性應用於程式集和模塊
[assembly: AssemblyTitle("assembly 4.6.1")]
[module: CLSCompliant(true)]
 1 //示例:將特性應用於方法、方法參數和方法返回值
 2 
 3 //預設:應用於方法
 4 [SomeAttr] 
 5 int Method1() { return 0; } 
 6 
 7 //指定應用於方法
 8 [method: SomeAttr]
 9 int Method2() { return 0; } 
10 
11 //指定應用於返回值
12 [return: SomeAttr] 
13 int Method3() { return 0; }

 

五、特性的常見用途

  以下列表包含特性的幾個常見用途:

    (1)在 Web 服務中,使用 WebMethod 特性來標記方法,以指示該方法應該可通過 SOAP 協議進行調用。

    (2)描述當與本機代碼進行交互操作時如何封送方法參數。有關更多信息。

    (3)描述類、方法和介面的 COM 屬性。

    (4)使用 DllImportAttribute 類調用非托管代碼。

    (5)在標題、版本、說明或商標方面描述您的程式集。

    (6)描述要持久性序列化類的哪些成員。

    (7)描述如何映射類成員和 XML 節點以便進行 XML 序列化。

    (8)描述方法的安全要求。

    (9)指定用於強制安全性的特性。

    (10)由實時 (JIT) 編譯器控制優化,以便易於調試代碼。

    (11)獲取有關調用方的信息的方法。

 

六、創建自定義的特性

   通過定義一個特性類,可以創建您自己的自定義特性。該特性類直接或間接地從 Attribute 派生,有助於方便快捷地在元數據中標識特性定義。

 1     /// <summary>
 2     /// 角色特性
 3     /// </summary>
 4     /// RoleAttribute:特性的名稱,繼承 Attribute,為自定義特性
 5     [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct)]
 6     public class RoleAttribute : Attribute
 7     {
 8         private string _name;
 9 
10         /// <summary>
11         /// 啟用標識
12         /// </summary>
13         /// IsEnable:命名參數
14         public bool IsEnable { get; set; }
15 
16         /// <summary>
17         /// 構造函數
18         /// </summary>
19         /// <param name="name"></param>
20         /// name:定位參數
21         public RoleAttribute(string name)
22         {
23             _name = name;
24         }
25     }
1     [Role("Me", IsEnable = true)]   //調用特性的方式
2     public class OurClass
3     {
4 
5     }

  構造函數的參數是自定義特性的定位參數,任何公共的讀寫欄位或屬性都是命名參數。註意】 AttributeUsage 特性,在這裡它使得 Role 特性僅在類和 struct 聲明中有效。

 

1     [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = true)]  //AllowMultiple:該值指示能否為一個程式多次使用該特性
2     public class RoleAttribute : Attribute
3     {
4         //... ...
5     }
1     [Role("You")]            //在同一個類上多次使用
2     [Role("Me", IsEnable = true)]   
3     public class OurClass
4     {
5         //... ...
6     }

  【註意】如果特性類包含一個屬性,則該屬性必須為讀寫屬性。

 

七、使用反射訪問特性

   使用反射,可檢索用自定義特性定義的信息。主要方法是 GetCustomAttributes,它返回對象數組,這些對象在運行時等效於源代碼特性。

 1     /// <summary>
 2     /// 角色特性
 3     /// </summary>
 4     /// RoleAttribute:特性的名稱,繼承 Attribute,為自定義特性
 5     [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct)]
 6     public class RoleAttribute : Attribute
 7     {
 8         private string _name;
 9         /// <summary>
10         /// 啟用標識
11         /// </summary>
12         public bool IsEnable { get; set; }
13 
14         /// <summary>
15         /// 構造函數
16         /// </summary>
17         /// <param name="name"></param>
18         public RoleAttribute(string name)
19         {
20             _name = name;
21         }
22     }
RoleAttribute.cs
1     [Role("Me", IsEnable = true)]   
2     public class OurClass
3     {
4         //... ...
5     }

  概念上等效於

1     RoleAttribute role = new RoleAttribute("Me");
2     role.IsEnable = true;

  但是,直到查詢 OurClass 來獲取特性後才會執行此代碼。對 OurClass 調用 GetCustomAttributes 會導致按上述方式構造並初始化一個 RoleAttribute 對象。如果該類具有其他特性,則按相似的方式構造其他特性對象。然後 GetCustomAttributes 返回 RoleAttribute 對象和數組中的任何其他特性對象。之後就可以對此數組進行迭代,確定根據每個數組元素的類型所應用的特性,並從特性對象中提取信息。

   這裡,定義一個自定義特性,將其應用於若幹實體並通過反射進行檢索。

 1     /// <summary>
 2     /// 角色特性
 3     /// </summary>
 4     [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = true)]
 5     public class RoleAttribute : Attribute
 6     {
 7         private readonly string _name;
 8 
 9         /// <summary>
10         /// 啟用標識
11         /// </summary>
12         public bool IsEnable { get; set; }
13 
14         /// <summary>
15         /// 構造函數
16         /// </summary>
17         /// <param name="name"></param>
18         public RoleAttribute(string name)
19         {
20             _name = name;
21         }
22 
23         public string GetName()
24         {
25             return _name;
26         }
27     }
    class MyClass1 { }

    [Role("Me")]
    class MyClass2 { }

    [Role("Me"), Role("You", IsEnable = true)]
    class MyClass3 { }
 1     class Program
 2     {
 3         static void Main(string[] args)
 4         {
 5             Output(typeof(MyClass1));
 6             Output(typeof(MyClass2));
 7             Output(typeof(MyClass3));
 8 
 9             Console.Read();
10         }
11 
12         /// <summary>
13         /// 輸出
14         /// </summary>
15         /// <param name="t"></param>
16         static void Output(Type t)
17         {
18             Console.WriteLine($"Class: {t}");
19 
20             var attributes = t.GetCustomAttributes();
21             foreach (var attribute in attributes)
22             {
23                 var attr = attribute as RoleAttribute;
24 
25                 if (attr == null)
26                 {
27                     return;
28                 }
29 
30                 Console.WriteLine($"    Name: {attr.GetName()}, IsEnable: {attr.IsEnable}");
31             }
32         }
33     }

 

 

 

 

 

 

傳送門

  《只是想簡單說下表達式樹 - Expression Trees

  《只是想簡單說下序列化

 


【參考】微軟官方文檔


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 本文主要是對unity中如何在Android和iOS中調用Native API進行介紹。 首先unity支持在C#中調用C++ dll,這樣可以在Android和iOS中提供C++介面在unity中調用。利用這一特性,可以擴展unity的功能。例如集成和調用第三方庫。同時為了滿足對unity介面的一 ...
  • 本次要分享的是利用windows+nginx+iis+redis+Task.MainForm組建分散式架構,上一篇分享文章製作是在windows上使用的nginx,一般正式發佈的時候是在linux來配置nginx,我這裡測試分享內容只是起引導作用;下麵將先給出整個架構的核心節點簡介,希望各位多多點贊 ...
  • .NET Core 超強性能測試組件BenchmarkDotNet 支持Full .NET Framework, .NET Core (RTM), Mono。 BenchmarkDotNet支持 C#, F#, 和Visual Basic,可以跨平臺運行。 而且支持各種報表導出,相當的方便。 Git ...
  • 命名空間:(記得引入ASPJPEGLib.dll) usingAspose.Words; 1.創建word模版,使用MergeFeild綁定數據 新建一個Word文檔,命名為Template.doc 打開Template.doc必須在菜單的"插入→文檔部件→域”找到MergeField並輸入相應的域 ...
  • Aspose.Cells導出excel,處理Datatable,下載地址編碼(中文),虛擬路徑&物理路徑 ...
  • ColorConsole htmlagilitypack.1.4.9.5 經測試效率比 CsQueryLaster 高 csvhelper Extend Devlib系列一套 itextsharp litedb log4net microsoft.bcl一套,.net4 await 用 MySql. ...
  • ADO.NET:數據訪問技術 就是將C#和MSSQL連接起來的一個紐帶 可以通過ADO.NET將記憶體中的臨時數據寫入到資料庫中也可以將資料庫中的數據提取到記憶體中供程式調用 所有數據訪問技術的基礎 連接資料庫基本格式:需要兩個類1、資料庫連接類 SqlConnection2、資料庫操作類 SqlCom ...
  • 添加引用InTheHand.Net.Personal.dll 首先創建一個藍牙類 然後就是搜索設備 藍牙的配對 客戶端 伺服器端 基本上就是這些吧! ...
一周排行
    -Advertisement-
    Play Games
  • 前言 本文介紹一款使用 C# 與 WPF 開發的音頻播放器,其界面簡潔大方,操作體驗流暢。該播放器支持多種音頻格式(如 MP4、WMA、OGG、FLAC 等),並具備標記、實時歌詞顯示等功能。 另外,還支持換膚及多語言(中英文)切換。核心音頻處理採用 FFmpeg 組件,獲得了廣泛認可,目前 Git ...
  • OAuth2.0授權驗證-gitee授權碼模式 本文主要介紹如何筆者自己是如何使用gitee提供的OAuth2.0協議完成授權驗證並登錄到自己的系統,完整模式如圖 1、創建應用 打開gitee個人中心->第三方應用->創建應用 創建應用後在我的應用界面,查看已創建應用的Client ID和Clien ...
  • 解決了這個問題:《winForm下,fastReport.net 從.net framework 升級到.net5遇到的錯誤“Operation is not supported on this platform.”》 本文內容轉載自:https://www.fcnsoft.com/Home/Sho ...
  • 國內文章 WPF 從裸 Win 32 的 WM_Pointer 消息獲取觸摸點繪製筆跡 https://www.cnblogs.com/lindexi/p/18390983 本文將告訴大家如何在 WPF 裡面,接收裸 Win 32 的 WM_Pointer 消息,從消息裡面獲取觸摸點信息,使用觸摸點 ...
  • 前言 給大家推薦一個專為新零售快消行業打造了一套高效的進銷存管理系統。 系統不僅具備強大的庫存管理功能,還集成了高性能的輕量級 POS 解決方案,確保頁面載入速度極快,提供良好的用戶體驗。 項目介紹 Dorisoy.POS 是一款基於 .NET 7 和 Angular 4 開發的新零售快消進銷存管理 ...
  • ABP CLI常用的代碼分享 一、確保環境配置正確 安裝.NET CLI: ABP CLI是基於.NET Core或.NET 5/6/7等更高版本構建的,因此首先需要在你的開發環境中安裝.NET CLI。這可以通過訪問Microsoft官網下載並安裝相應版本的.NET SDK來實現。 安裝ABP ...
  • 問題 問題是這樣的:第三方的webapi,需要先調用登陸介面獲取Cookie,訪問其它介面時攜帶Cookie信息。 但使用HttpClient類調用登陸介面,返回的Headers中沒有找到Cookie信息。 分析 首先,使用Postman測試該登陸介面,正常返回Cookie信息,說明是HttpCli ...
  • 國內文章 關於.NET在中國為什麼工資低的分析 https://www.cnblogs.com/thinkingmore/p/18406244 .NET在中國開發者的薪資偏低,主要因市場需求、技術棧選擇和企業文化等因素所致。歷史上,.NET曾因微軟的閉源策略發展受限,儘管後來推出了跨平臺的.NET ...
  • 在WPF開發應用中,動畫不僅可以引起用戶的註意與興趣,而且還使軟體更加便於使用。前面幾篇文章講解了畫筆(Brush),形狀(Shape),幾何圖形(Geometry),變換(Transform)等相關內容,今天繼續講解動畫相關內容和知識點,僅供學習分享使用,如有不足之處,還請指正。 ...
  • 什麼是委托? 委托可以說是把一個方法代入另一個方法執行,相當於指向函數的指針;事件就相當於保存委托的數組; 1.實例化委托的方式: 方式1:通過new創建實例: public delegate void ShowDelegate(); 或者 public delegate string ShowDe ...