自定義屬性的作用
有時候我們需要給一個類或者類中的成員加上一些屬性或者附加信息,讓類或者變量的功能更明確可控制的細粒度更高,打個簡單的比方:數據庫里面的一張表,表中的每一個字段都有很多屬性,如是否主鍵,默認值,注釋信息等等,我們在編寫實體類的時候,如何表示這些信息呢?通過自定義屬性可以實現。
自定義屬性的實現步驟
我說了不算,權威說了算:
- 聲明一個類,並將 AttributeUsageAttribute 屬性應用到該類中。類的名稱即為新屬性的名稱
- 聲明該類從 System.Attribute 繼承:
- 定義 Private 字段來存儲屬性值:
- 需要時,請為屬性創建構造函數:
- 為屬性 (Attribute) 定義方法、字段和屬性 (Property):
實例一個:
屬性類(和相關枚舉)
/// 數據庫字段的用途。
/// </summary>
public enum EnumDBFieldUsage
{
/// <summary>
/// 未定義。
/// </summary>
None = 0x00,
/// <summary>
/// 用於主鍵。
/// </summary>
PrimaryKey = 0x01,
/// <summary>
/// 用於唯一鍵。
/// </summary>
UniqueKey = 0x02,
/// <summary>
/// 由系統控制該字段的值。
/// </summary>
BySystem = 0x04
}
[AttributeUsage(AttributeTargets.Property, Inherited = true)]
public class DBFieldAttribute:Attribute
{
EnumDBFieldUsage m_usage;
string m_strFieldName;
string m_strDescription;
object m_defaultValue;
public DBFieldAttribute(string strFieldName,object defaultValue,EnumDBFieldUsage usage,string strDescription)
{
m_strFieldName = strFieldName;
m_defaultValue = defaultValue;
m_usage = usage;
m_strDescription = strDescription;
}
public DBFieldAttribute(string fieldName) : this(fieldName,null, EnumDBFieldUsage.None,null)
{ }
public DBFieldAttribute(string fieldName, EnumDBFieldUsage usage) : this(fieldName, null,usage, null)
{ }
// 獲取該成員映射的數據庫字段名稱。
public string FieldName
{
get
{
return m_strFieldName;
}
set
{
m_strFieldName = value;
}
}
// 獲取該字段的默認值
public object DefaultValue
{
get
{
return m_defaultValue;
}
set
{
m_defaultValue = value;
}
}
}
此代碼說明了如何制作自定義屬性類。其實跟一般的類的區別就是此類繼承自Attribute,加上AttributeUsage是屬性上的屬性,是可選的。
數據訪問層實體類:
{
string m_strTableName;
int m_nID;
string m_strName;
string m_password;
public DalObj(string strTableName)
{
m_strTableName = strTableName;
}
[DBField("id",EnumDBFieldUsage.PrimaryKey)]
public int ID
{
get { return m_nID; }
set { m_nID = value; }
}
[DBField("name",DefaultValue="游客")]
public string Name
{
get { return m_strName; }
set { m_strName = value; }
}
[DBField("pwd")]
public string PassWord
{
get { return m_password; }
set { m_password = value; }
}
}
此代碼說明了如何使用自定義的屬性。有兩點需要注意的地方
第一:類名可以跟自定義的類名一樣,也可以加上或減去后面的Attribute,本例子中就是使用的時候跟自定義的類名減少了“Attribute”。
第二:屬性參數填寫方法,如果自定義屬性類(例子中DBFieldAttribute)自己的構造函數帶參數,那么這些參數是必選的,可以重載構造函數以滿足不同組合,必選參數填完之后,可以繼續給自定義屬性類中的公共成員帶命名地賦值,如例子中的 DefaultValue="游客" 一句就是命名參數。
遍歷自定義屬性的代碼:
StringBuilder sb = new StringBuilder();
foreach (PropertyInfo proInfo in dalObj.GetType().GetProperties())
{
object[] attrs = proInfo.GetCustomAttributes(typeof(DBFieldAttribute), true);
if (attrs.Length == 1)
{
DBFieldAttribute attr = (DBFieldAttribute)attrs[0];
sb.Append(attr.FieldName + ":" + (attr.DefaultValue == null ? "null" : attr.DefaultValue.ToString()) + "\r\n");
}
}
MessageBox.Show(sb.ToString());
此代碼說明了如何檢索自定義屬性的值,主要用到了GetCustomAttributes來獲取屬性值。