.NET 特性随笔

  .net中有特性和属性,很多时候初学者会认为属性和特性是一回事儿,实际上,特性是.NET框架中一门技术,通俗的说,我们可以把特性理解成为一个特殊的类,他继承Attribute 来对代码进行特殊的约束。

  自定义的特性就是我们自己定义的一个类,其继承了Attrubute,如:

  我们对表的字段MODEL做一个简单的特性约定类:

 

View Code
 1 /// <summary>
 2     /// 数据表列名映射
 3     /// </summary>
 4     [AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
 5     public sealed class ColumnMap : Attribute
 6     { 
 7         public ColumnMap()
 8         {
 9             //构造
10           }
11         /// <summary>
12         /// 映射字段
13      /// </summary>
14         /// <param name="_ColumnName">列字段名</param>
15         /// <param name="_ColumnLen">长度</param>
16         /// <param name="_DataType">数据类型</param>
17         /// <param name="_Remark">字段说明</param>
18         /// <param name="_IsNull">是否允许空值</param>
19         /// <param name="_PrimaryKey">是否为主键</param>
20         /// <param name="_Mark">是否为自增或默认值,True:则不对此列进行Insert与Update操作</param>
21         public ColumnMap(string _ColumnName, string _ColumnLen, object _DataType, string _Remark, bool _IsNull, bool _PrimaryKey, bool _Mark)
22         {
23             this.ColumnName = _ColumnName;
24             this.ColumnLen = _ColumnLen;
25             this.DataType = _DataType;
26             this.Remark = _Remark;
27             this.IsNull = _IsNull;
28             this.PrimaryKey = _PrimaryKey;
29             this.Mark = _Mark;
30         }
31         /// <summary>
32         /// 列字段名
33         /// </summary>
34         public string ColumnName { get; set; }
35         /// <summary>
36         /// 长度
37         /// </summary>
38         public string ColumnLen { get; set; }
39         /// <summary>
40         /// 数据类型
41         /// </summary>
42         public object DataType { get; set; }
43         /// <summary>
44         /// 字段说明
45         /// </summary>
46         public string Remark { get; set; }
47         /// <summary>
48         /// 是否允许空值
49         /// </summary>
50         public bool IsNull { get; set; }
51         /// <summary>
52         /// 是否为主键
53         /// </summary>
54         public bool PrimaryKey { get; set; }
55         /// <summary>
56         /// 是否为自增或默认值,True则不对此列进行INSERT和UPDATE
57         /// </summary>
58         public bool Mark { get; set; }
59     }

  接下来使用这个特性来约定MODEL中的属性:

View Code
 1 /// <summary>
 2     /// 权限菜单,TablMap请自行定义
 3     /// </summary>
 4     [Serializable]
 5     [TableMap("Affair_Parames", "Role_Menu")]
 6     public class Role_Menu
 7     {
 8         /// <summary>
 9         /// 编号
10         /// </summary>
11         [ColumnMap("Menu_Id", null, DbType.Int32, "自动编号", false, true, true)]
12         public int? Menu_Id { get; set; }
13 
14         /// <summary>
15         /// 功能名称
16         /// </summary>
17         [ColumnMap("Menu_Name", "50", DbType.String, "功能名称", false, false, false)]
18         public string Menu_Name { get; set; }
19 
20         /// <summary>
21         /// 功能层级深度
22         /// </summary>
23         [ColumnMap("Menu_Depth", null, DbType.Int32, "功能层级深度", false, false, false)]
24         public int Menu_Depth { get; set; }
25 
26         /// <summary>
27         /// 父级功能
28         /// </summary>
29         [ColumnMap("Menu_Parent", null, DbType.Int32, "父级功能", false, false, false)]
30         public int Menu_Parent { get; set; }
31 
32         /// <summary>
33         /// 功能状态
34         /// </summary>
35         [ColumnMap("Menu_state", null, DbType.Int32, "功能状态", false, false, false)]
36         public int Menu_state { get; set; }
37 
38         /// <summary>
39         /// 功能类型
40         /// </summary>
41         [ColumnMap("Menu_Type", null, DbType.Int32, "功能类型", false, false, false)]
42         public int Menu_Type { get; set; }
43 
44         /// <summary>
45         /// 功能说明
46         /// </summary>
47         [ColumnMap("Menu_Remarks", "500", DbType.String, "功能说明", false, false, false)]
48         public string Menu_Remarks { get; set; }
49 
50         /// <summary>
51         /// 功能指向
52         /// </summary>
53         [ColumnMap("Menu_Link", "500", DbType.String, "功能指向", false, false, false)]
54         public string Menu_Link { get; set; }
55 
56         /// <summary>
57         /// 功能所在层级排序 
58         /// </summary>
59         [ColumnMap("Menu_Index", null, DbType.Int32, "功能所在层级排序", false, false, false)]
60         public int Menu_Index { get; set; }
61 
62         /// <summary>
63         /// 功能事件参数
64         /// </summary>
65         [ColumnMap("Menu_Task", "150", DbType.String, "功能事件参数", false, false, false)]
66         public string Menu_Task { get; set; }
67     }

现在已经使用ColumnMap对Role_Menu类中的属性是行约束。

  那么这个特性的约束有什么用?

    在没有后继调用的情况下,这个约束什么用也没用,只起到个说明功能!接下来,就调用这个特性。那么,如何来调用这个特性呢?反射

  首先我们先定义一个类及其方法:

View Code
 1 /// <summary>
 2     /// 获取指定属性对象的特性
 3     /// </summary>
 4     /// <typeparam name="T"></typeparam>
 5     public sealed class AttributeProperty<T> where T : class
 6     {
 7         public static T GetTableMapAttribute(PropertyInfo t)
 8         {
 9             T Map = default(T);
10             T[] MapAttributes = t.GetCustomAttributes(typeof(T), true) as T[];
11             if (MapAttributes.Length > 0)
12             {
13                 Map = MapAttributes[0];
14             }
15             return Map;
16         }
17 
18     }

  接下来就调用这个类,来获取前面所做的MODEL的特性

 

Role_Menu Menu = new  Role_Menu();
PropertyInfo[] Pinfos= Menu.GetType().GetProperties();
//也可以
/*
PropertyInfo[] Pinfos= typeof(Role_Menu).GetProperties();
*/
/*
MethodInfo[]....针对方法
*/

foreach (PropertyInfo P in Pinfos) {
  ColumnMap Map = AttributeProperty<ColumnMap>.GetTableMapAttribute(P);
 if (Map != null)
  {
    //这里你想做什么就做什么,ColumnMap在指定给Role_Menu类时的特性参数值就都在这里了***原数据***********
 }
}

如果想获取某个类的特性,可以采用下面这个方法

View Code
 1 /// <summary>
 2     /// 获取指定类对象的特性
 3     /// </summary>
 4     public sealed class AttributeTag<T, A>
 5         where T : class
 6         where A : class
 7     {
 8         /// <summary>
 9         /// 获取表所映射的特性
10         /// </summary>
11         /// <param name="t">对象</param>
12         /// <returns></returns>
13         public static A GetTableMapAttribute(T t)
14         {
15             A Map = default(A);
16             Type MapType = t.GetType();
17             A[] MapAttributes = MapType.GetCustomAttributes(typeof(A), true) as A[];
18             if (MapAttributes.Length > 0)
19             {
20                 Map = MapAttributes[0];
21             }
22             return Map;
23         }
24     }

其中A:特性类,T:使用特性的类

 

小结:

  特性就是一个类,继承Attribute,可以应用于类,方法,属性等

  要获取特性的内容,则需要通地反射的方式来得到。

posted on 2012-12-24 19:24  FLASHFYZ  阅读(142)  评论(0编辑  收藏  举报

导航