元數據,就是C#中封裝的一些類,無法修改.類成員的特性被稱為元數據中的註釋. 1、什麼是特性 (1)屬性與特性的區別 屬性(Property):屬性是面向對象思想里所說的封裝在類裡面的數據欄位,Get,Set方法。 特性(Attribute): 官方解釋:特性是給指定的某一聲明的一則附加的聲明性信息 ...
元數據,就是C#中封裝的一些類,無法修改.類成員的特性被稱為元數據中的註釋.
1、什麼是特性
(1)屬性與特性的區別
屬性(Property):屬性是面向對象思想里所說的封裝在類裡面的數據欄位,Get,Set方法。
特性(Attribute): 官方解釋:特性是給指定的某一聲明的一則附加的聲明性信息。 允許類似關鍵字的描述聲明。它對程式中的元素進行標註,如類型、欄位、方法、屬性等。從.net角度看,特性是一種 類,這些類繼承於System.Attribute類,用於對類、屬性、方法、事件等進行描述,主要用在反射中。但從面向對象的級別看,其實Attribute是類型級別的,而不是對象級別。
Attributes和.net文件的元素據保存在一起,可以用來向運行時描述你的代碼,或者在程式運行的時候影響程式的行為。
2、特性的應用
(1).net中特性用來處理多種問題,比如序列化、程式的安全特性、防止即時編譯器對程式代碼進行優化從而代碼容易調試等等。
定植特性的本質上是一個類的元素上去添加附加信息,併在運行其通過反射得到該附加信息(在使用數據實體對象時經常用到)
(2)Attribute 作為編譯器的指令時的應用
Conditional:起條件編譯的作用,只有滿足條件,才允許編譯器對它的代碼進行編譯。一般在程式調試的時候使用
DllImport: 用來標記費.net的函數,表明該方法在一個外部的DLL中定義。
Obsolete: 這個屬性用來標記當前的方法已經廢棄,不再使用
註:Attribute是一個類,因此DllImport也是一個類,Attribute類是在編譯的時候實例化,而不是像通常那樣在運行時實例化。
CLSCompliant: 保證整個程式集代碼遵守CLS,否則編譯將報錯。
3、自定義特性
使用AttributeUsage,來控制如何應用新定義的特性
[AttributeUsageAttribute(AttributeTargets.All 可以應用到任何元素
,AllowMultiple=true, 允許應用多次,我們的定值特性能否被重覆放在同一個程式實體前多次。
,Inherited=false,不繼承到派生
)]
特性也是一個類,必須繼承於System.Attribute類,命名規範為“類名”+Attribute。不管是直接還是間接繼承,都會成為一個特性類,特性類的聲明定義了一種可以放置在聲明之上新的特性。
public class MyselfAttribute:System.Attribute
4、自定義特性案例
以下用一個類似於Hibernate中Session的Save()方法效果,自動持久化對象信息到資料庫來說明自定義特性的使用。
(1)建立Dept表
Create Table Dept( deptNo int identity(1,1) primary key, dname nvarchar(10) not null, description nvarchar(100) ) Go -- 何問起 hovertree.com
(2)自定義特性類
/**************自定義特性類*****************/ /// <summary> /// 作用:用來說明表名是什麼 /// AttributeUsage:說明特性的目標元素是什麼 /// AttributeTargets.Class:代表目標元素為Class /// </summary> [AttributeUsage(AttributeTargets.Class)] public class TableAttribute : Attribute{ /// <summary> /// 表名 /// </summary> public string TableName { get; set; } #region 構造方法,可選的 public TableAttribute() { } public TableAttribute(string tableName) { this.TableName = tableName; } #endregion } /**************自定義特性類*****************/ /// <summary> /// 作用:說明列是否為自動增長列 /// </summary> [AttributeUsage(AttributeTargets.Property)] class IdentityAttribute: Attribute { /// <summary> /// true:是; false:否 /// </summary> public bool IsIdentity { get; set; } } /****************實體類***************/ /// <summary> /// 有意將類名定義成與表名不一致 /// 用Table特性來說明實體類對應的表名是什麼 /// </summary> [Table(TableName = "Dept")] public class Department { /// <summary> /// 部門編號,用特性標註為自動增長 /// </summary> [Identity(IsIdentity=true)] public int DeptNo { get; set; } /// <summary> /// 部門名稱 /// </summary> public string Dname { get; set; } /// <summary> /// 部門描述 /// </summary> public string Description { get; set; } public Department( string name, string desc) { Dname = name; Description = desc; } } /****************執行持久化操作類***************/ /// <summary> /// 執行持久化操作類 /// </summary> public class ADOManager { /// <summary> /// 將對象的屬性值作為表中對應列的值來添加 /// </summary> /// <param name="obj">要添加的對象</param> public int Save(Object obj) { //1.取得類名:代表表名,用到反射 string tableName = obj.GetType().Name; //如果類有TableAttribute特性,在採用特性說明的類名 TableAttribute attr = Attribute.GetCustomAttribute(obj.GetType(), typeof(TableAttribute)) as TableAttribute; if (attr != null) {//說明類加了Table特性 tableName = attr.TableName;//取得表名 } //sql語句模板:insert into Dept(deptno,dname,description) values('2','',''); StringBuilder sql = new StringBuilder("insert into "); sql.Append(tableName); sql.Append(" ("); //迴圈對象的屬性名:取得列名 foreach (PropertyInfo item in obj.GetType().GetProperties()) { //取得是否有自動增長的特性 IdentityAttribute att = Attribute.GetCustomAttribute(item, typeof(IdentityAttribute)) as IdentityAttribute; if (att == null || !att.IsIdentity) {//沒有,則添加列 sql.Append(item.Name); sql.Append(","); } } //去除最後一個逗號' sql.Remove(sql.Length - 1, 1); sql.Append(") values("); //迴圈取出對象的屬性值:為列賦值 foreach (PropertyInfo item in obj.GetType().GetProperties()) { //取得是否有自動增長的特性 IdentityAttribute att = Attribute.GetCustomAttribute(item, typeof(IdentityAttribute)) as IdentityAttribute; if (att == null) {//沒有,則追加列的值 //GetValue():obj代表什麼對象,null代表沒有參數 sql.Append("'" + item.GetValue(obj, null) + "'"); sql.Append(","); } } //去除最後一個逗號' sql.Remove(sql.Length - 1, 1); sql.Append(")"); //查看完整的sql語句 Console.WriteLine(sql.ToString()); //執行sql語句 SqlConnection conn = new SqlConnection("server=.;database=test;integrated security=true"); SqlCommand comm = new SqlCommand(sql.ToString(), conn); conn.Open(); int r = comm.ExecuteNonQuery(); conn.Close(); return r;//返回執行結果 } } /* 何問起 hovertree.com */ /****************測試類關鍵代碼***************/ Department dept = new Department("開發部", "負責產品的研發"); ADOManager manager = new ADOManager(); int r = manager.Save(dept); Console.WriteLine(r==0?"失敗":"成功");
小結:
C#的特性類和Java中的元註釋一樣
特性其本質就是一個繼承了Attribute的類
使用使可以省略Attribute結尾,如:TableAttribute =>> Table
特性將會影響其作用的目標元素的編譯和運行過程
使用自定義特性的步驟:
1. 定義特性類,類必須直接或間接繼承字Attribute類
2. 在需要用的該特性的目標元素上添加特性
3. 在使用添加了特性的類的使用,獲取並使用自特定特性的信息
推薦:http://www.cnblogs.com/roucheng/p/dushubiji.html