反射簡介 C 特性和反射

2022-03-07 22:26:34 字數 3785 閱讀 9795

.net編譯器的任務之一就是為所有定義和引用的型別生成元資料描述。除了程式集中標準的元資料外,.net平台還支援特定(attribute)把更多的元資料嵌入到程式集中。

.net特性擴充套件了抽象的system.attribute基類,.net中有很多預定義的特性,例如:[dllimport]、[obsolete]和[serializable]等等。

看乙個obsolete使用的例子,obsolete特性用來標記不用的類或成員,當其他程式試圖訪問該項的時候,將會得到乙個警告或錯誤描述。

static

class

stringutil

[obsolete(

"this legacy method should not be used

", true

)]

public

static

string legacyreversestring(string

str)

}class

program

}

使用上面的**,我們就會的到乙個錯誤訊息,提示我們不應該在使用這個方法了

當然,我們也可以通過**來新增自定義特性,在開始自定義特性之前,我們需要知道以下概念。

在**中,我們可以建立自定義的特性型別,但是這個型別一定要直接或間接從system.attribute派生。下面我們就定義了乙個tableattribute特性:

[attributeusage(attributetargets.class, inherited=false, allowmultiple=false

)]public

class

tableattribute : attribute

public tableattribute(string

tablename)

public

string tablename

}

注意:對乙個特性類名使用attribute字尾是乙個慣例。然而,當我們把特性新增到乙個程式實體,可以選擇省略atrribute字尾。編譯器會首先在system.attribute的派生類中查詢被新增的特性類。如果沒有找到,那麼編譯器會新增 attribute字尾繼續查詢。

例如:當我們在**中使用的時候,特性表現為[obsolete],但是實際上型別是obsoleteattribute,而不是**中的obsolete。當.net framework進行名稱轉換的時候,所有的.net特性(包括自定義特性)都將加上乙個attribute標記的字尾。

在上面的自定義特性中,有下面一行**,我們給自定義特性應用了乙個attributeusage特性。

[attributeusage(attributetargets.class, inherited=false, allowmultiple=false)]
attributeusage類是乙個預定義特性類,通過這個特性,我們可以控制自定義特性的使用,它描述了乙個定製特性如和被使用。

[serializable]

[attributeusage(attributetargets.class, inherited = true

)][comvisible(

true

)]public

sealed

class

attributeusageattribute : attribute

public

bool inherited

public attributetargets validon

}

通過**可以看到,attributeusage有三個屬性:

從上面的介紹可以看到,建立自定義特性的大概步驟:

宣告特性類,由 system.attribute 直接或間接派生

使用attributeusage特性來控制自定義特性

宣告特性類建構函式

當我們使用特性的時候,只是給程式集新增了一些元資料。當結合反射使用的時候,特性就能發揮很大的作用了。

下面看乙個特性和反射結合的例子,在例子中自定義了table和column特性,然後把這些特性應用到了我們的user型別上面;然後結合乙個自定義的orm型別,將物件的inster()操作轉換成sql語句。

namespace

attributetest

public tableattribute(string

tablename)

public

string tablename

}[attributeusage(attributetargets.property, inherited=false, allowmultiple=false

)]

public

class

columnattribute:attribute

public columnattribute(string

columnname)

public columnattribute(string

colunmname, dbtype dbtype)

public

string columnname

public dbtype dbtype

}public

class

customizeorm}}

foreach (var item in

columnvaluedict)

sqlstr.remove(sqlstr.length - 1, 1);"

) values('");

foreach (var item in

columnvaluedict)

sqlstr.remove(sqlstr.length - 2, 2);"

)"); console.writeline(sqlstr.tostring());}}

[table(

"users")]

public

class

user

[column(columnname="

name

",dbtype=dbtype.string)]

public

string username

[column(columnname = "

age", dbtype =dbtype.int32)]

public

int age

}class

program

;customizeorm.insert(user);

console.read();}}

}

**的執行結果為:

從這個例子中可以看到,通過特性給程式集加入的元資料,可以在執行時被反射程式得到並使用。

通過il**可以看到特性的簡化,**中我們使用table、column對user型別進行修飾,在il**中都加上了attribute字尾;同時還可以看到,這些特性都變成了user型別的元資料。

通過本文介紹了.net特性,同時介紹了自定義特性需要的基本知識。

特性本身只是給程式集新增一些元資料,當結合反射使用的時候,這些被新增的元資料才能發揮更大的作用。

C 反射特性 一)

using system using system.collections.generic using system.linq using system.text using system.reflection namespace reflectionexam set private string ...

C 反射技術簡介

如果你要獲取到這個類的物件例項可以這麼做 以string類為例子 string str system.string string exp string activator.createinstance str 如果你要得到這個類的型別資訊可以這麼做 type exptype type.gettype...

反射與特性

反射 程式在執行時,可以檢視其它程式集或其本身的元資料。乙個執行的程式檢視本身的元資料或者其他程式集的元資料的行為叫做反射。myclass.cs class myclass 定義乙個用來反射查詢的元資料 public void test program.cs static void main str...