前言
想要靈性的使用C#反射機制射亏,特性(Attribute)的使用是必不可少的反砌。
C# 特性(Attribute) 簡介
Attribute 中文譯為 屬性。而C#特征已有 Property 屬性一詞费奸。
講究先來后到包雀,Attribute被譯為了特性。
特性(Attribute)是用于在運行時傳遞程序中各種元素(比如類孩饼、方法髓削、結構、枚舉镀娶、組件等)的行為信息的聲明性標簽立膛。您可以通過使用特性向程序添加聲明性信息。一個聲明性標簽是通過放置在它所應用的元素前面的方括號([ ])來描述的梯码。
"標簽"這個詞很好的解釋了Attribute的作用宝泵。
還有"注釋"一詞
特性是可以添加到編程元素(例如程序集,類型轩娶,成員和參數(shù))的注釋儿奶。它們存儲在程序集的元數(shù)據(jù)中,可以使用反射API在運行時訪問罢坝。例如廓握,框架定義了ObsoleteAttribute,它可以應用于類型或成員嘁酿,以指示已棄用類型或成員隙券。
特性(Attribute)用于添加元數(shù)據(jù),如編譯器指令和注釋闹司、描述娱仔、方法、類等其他信息游桩。.Net 框架提供了兩種類型的特性:預定義特性和自定義特性牲迫。
預定義特性(Attribute)
.Net 框架提供了三種預定義特性:
- AttributeUsage
- Conditional
- Obsolete
代碼摘選自菜鳥教程
預定義特性 AttributeUsage 描述了如何使用一個自定義特性類。它規(guī)定了特性可應用到的項目的類型借卧。
規(guī)定該特性的語法如下:
[AttributeUsage(
validon,
AllowMultiple=allowmultiple,
Inherited=inherited
)]
其中:
- 參數(shù) validon 規(guī)定特性可被放置的語言元素盹憎。它是枚舉器 AttributeTargets 的值的組合。默認值是 AttributeTargets.All铐刘。
- 參數(shù) allowmultiple(可選的)為該特性的 AllowMultiple 屬性(property)提供一個布爾值陪每。如果為 true,則該特性是多用的。默認值是 false(單用的)檩禾。
- 參數(shù) inherited(可選的)為該特性的 Inherited 屬性(property)提供一個布爾值挂签。如果為 true,則該特性可被派生類繼承盼产。默認值是 false(不被繼承)饵婆。
例如:
[AttributeUsage(AttributeTargets.Class |
AttributeTargets.Constructor |
AttributeTargets.Field |
AttributeTargets.Method |
AttributeTargets.Property,
Inherited = true,
AllowMultiple = true)]
public class BaseAttribute : Attribute
...
創(chuàng)建自定義特性(Attribute)
.Net 框架允許創(chuàng)建自定義特性,用于存儲聲明性的信息戏售,且可在運行時被檢索侨核。該信息根據(jù)設計標準和應用程序需要,可與任何目標元素相關蜈项。
創(chuàng)建并使用自定義特性包含四個步驟:
- 聲明自定義特性
- 構建自定義特性
- 在目標程序元素上應用自定義特性
- 通過反射訪問特性
聲明自定義特性
定義一個用來存儲數(shù)據(jù)表名的類芹关,一個新的自定義特性應派生自 System.Attribute 類
using System;
namespace DataHelper.Attributes
{
/// <summary>
/// 該特性表明了該類可以用來生成sql語句,參數(shù)為空的情況下紧卒,則使用該類的名稱作為表名
/// </summary>
[System.AttributeUsage(AttributeTargets.Class, Inherited = true, AllowMultiple = false)]
public sealed class TableNameAttribute : Attribute
{
readonly string tableName;
/// <summary>
/// 指定表名
/// </summary>
/// <param name="tableName"></param>
public TableNameAttribute(string tableName = null)
{
if (string.IsNullOrEmpty(tableName))
tableName = this.GetType().Name;
this.tableName = tableName;
}
public string TableName
{
get { return tableName; }
}
}
}
使用自定義特性
[TableName("media")]
public class Media
{
...
}
獲取指定特性
/// <summary>
/// 獲得表名
/// 若沒有使用TableName 指定表名侥衬,則使用類名作為表名
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
private string GetTableName<T>()
{
var type = typeof(T);
var result = ((TableNameAttribute)type
.GetCustomAttributes(typeof(TableNameAttribute), false).FirstOrDefault())
?.TableName ?? type.Name;
return result;
}