C#的特性(Attribute)的應用

來源:互聯網
上載者:User

文章內容參考了nuaaflm的反射學習系列2-特性(Attribute),連結地址為:http://www.cnblogs.com/nuaalfm/archive/2008/09/07/1286195.html

因為打算寫一個簡單的ORM實現,所以上網上參考了些資料,現在先介紹一下需要用到的一個重要的技術,特性(Attribute)。因為原文的作者已經介紹得很詳細了,我就不自己寫了,直接COPY過來。由於原作者使用的是.net3.5的,我把代碼改成了2.0的版本。

 

先看一個簡單的例子
[Table(Name="UserInfo")]
public class UserInfo
{
當C#編譯器發現這個屬性有一個特性Table時,首先會把字串Attribute添加到這個名稱的後面,形成一個組合名稱TableAttribute,然後在其搜尋路徑的所有命名空間中搜尋有相同類名的類。但要注意,如果該特性名結尾是Attribute,編譯器就不會把該字串加到組合名稱中。所有的特性都是從System.Attribute類型上面派生的。
接著我們來看一下Table特性的定製格式
[AttributeUsageAttribute(AttributeTargets.Class, Inherited=true,AllowMultiple=false)]
public class TalbeAttribute:Attribute
{

    在定義類型時使用System.AttributeUsage特性來表明這個自訂特性的使用範圍,這裡使用了Class樣式,表示TableAttribute特性只能用在其它的Class類型前面,若放置在Interface或Struct類型前面,或者放在對象成員的前面則會出現編譯錯誤。這裡還是用語句 AllowMultiple=false 語句來表明對於一個類型,該特性只能用一次,若一個Class類型前面出現多個TableAttribute,則會出現編譯錯誤。若設定AllowMultiple=true,則該特性可以多次定義,也就是一個Class類型前面可以出現多個相同類型的特性。不過這裡我們假設一個對象只能映射到一個資料表上,沒有多重新對應,因此就指明對同一個類型該特性不能多次使用。Inherited參數設定為true,就表示應用到類或介面上的特性也可以自動應用到所派生的類或介面上。
我們再看一下定製TalbeAttribute特性的完整例子:

 

 

Code
[AttributeUsage(AttributeTargets.Class,AllowMultiple=false,Inherited=false)]
public class TableAttribute : Attribute
{
private string tableName;

public string TableName
{
get { return tableName; }
set { tableName = value; }
}

public TableAttribute()
{
this.tableName = null;
}

public TableAttribute(string tableName)
{
this.tableName = tableName;
}
}

 

 

特性也是一個Class類型,可以有多個建構函式,就像C#的new語句一樣,我們向類型附加特性時可以使用不同的初始化參數來指明使用特性的那個建構函式。我們附加特性時還可以使用“屬性名稱=屬性值”的方法來直接指明特性的屬性值。該特性中定義了一個TableName屬性,該屬性就是被修飾的對象所映射的資料庫表的名稱。

下面我們舉一個使用特性來進行O/RMapping的例子

使用者類:

 

Code
[Table("UserInfo")]
public class UserInfo
{
private int userId;

[Column("UserId",DbType.Int32)]
public int UserId
{
get { return userId; }
set { userId = value; }
}
private string userName;

[Column(UserName,DbType.String)]
public string UserName
{
get { return userName; }
set { userName = value; }
}

}

 

列特性:

 

Code
[AttributeUsage(AttributeTargets.Property,AllowMultiple=false,Inherited=false)]
public class ColumnAttribute : Attribute
{
public ColumnAttribute()
{
this.columnName = null;
this.dbType = DbType.String;
}

public ColumnAttribute(string columnName)
{
this.columnName = columnName;
}

public ColumnAttribute(string columnName, DbType dbType)
: this(columnName)
{
this.dbType = dbType;
}

private string columnName;

public string ColumnName
{
get { return columnName; }
set { columnName = value; }
}
private DbType dbType;

public DbType DbType
{
get { return dbType; }
set { dbType = value; }
}

}

 運行類:

 

Code
class Program
{
static void Main(string[] args)
{

UserInfo userInfo = new UserInfo();
Type type = userInfo.GetType();

TableAttribute ta = (TableAttribute)type.GetCustomAttributes(false)[0];
Console.WriteLine("資料表名:" + ta.TableName);
PropertyInfo[] infos = type.GetProperties();
foreach (PropertyInfo info in infos)
{
object[] attributes = info.GetCustomAttributes(false);
foreach (object att in attributes)
{
if (att is ColumnAttribute)
{
ColumnAttribute ca = att as ColumnAttribute;
string cn = ca.ColumnName == null ? info.Name : ca.ColumnName;
Console.WriteLine("欄位名:" + cn);
Console.WriteLine("欄位類型:" + ca.DbType);
}
}
}
}

 

下面是運行結果的:

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.