C 高階之特性(Attribute)

2022-02-22 04:56:51 字數 3410 閱讀 8856

相信只要是用過.net mvc的開發都用過特性,例如最基礎的httpmethodattribute特性,用來給介面進行請求方式限定的,等等諸如此類的特性,數不勝數。

那麼什麼是特性?

特性就是乙個類,直接或者間接繼承自attribute,特性本身沒有任何作用

特性的使用方法有兩種:

[range(0,10

)] [test]

///分開單獨使用

public

int hight

[test, range(

0, 10

)]

///合併使用,通過逗號分隔

public

string name

attribute的使用規則,一般通過在特性類上使用attributeusage特性來進行設定

這個特性有三個屬性:

allowmultiple:是否允許重複使用;

inherited:是否可以被繼承;

建構函式有attributetargets型別的引數,主要用來設定特性的使用場景(類、介面、屬性、字段……)

特性的使用場景:

用來做標記,通過判斷類、屬性……是否有這個特性,來進行一些業務邏輯上的判斷,比如:

具體是通過system.reflection程式集提供的反射功能來進行特性獲取,

譬如判斷乙個型別是否具有某個特性,使用的是isdefined方法,

獲取乙個類的所有特性,使用的是getcustomattributes方法,獲取的是乙個object,可以通過as進行強轉為需要判斷的型別;

obsoleteattribute:可以通過新增這個特性,對類、屬性、介面等進行**過期設定;

conditionalattribute:通過在方法上設定這個特性,可以遮蔽掉對該方法的所有呼叫(不過支援返回值是void的方法,畢竟只有這樣才不會有在呼叫的時候有上下文);

經常看到錯誤日誌裡面有很詳細的資訊,具體到了某某檔案多少行哪個方法出錯等等,其實微軟也提供了對應的特性,支援我們自己檢視這些內容:

///

//////

///呼叫的檔案物理路徑

///被呼叫的行

///呼叫的方法

public

void call2(string

str,

[callerfilepath]

string filepath = ""

, [callerlinenumber]

int num = 0

, [callermembername]

string name = ""

)

可以通過繼承validationattribute,並重寫isvalid方法即可實現自定義的屬性繫結校驗。

///

//////

[attributeusage(attributetargets.all,allowmultiple = true,inherited = true

)]

public

class

rangeattribute : validationattribute

public

int? maxnum

public

int? minnum

public

override

bool isvalid(object

value)

}

舉個例子,比如我想要對乙個列表進行多個欄位的檢索,比如這個實體

///

///全域性搜尋查詢demo實體

/// public

class

serachentity

//////

中文名

///[globalserach]

[export(

"中文名")]

public

string cname

//////

英文名

///[globalserach]

[export(

"英文名")]

public

string ename

//////

位址

///[globalserach]

[export("位址

")]public

string address

//////

ip

/// [export("

ip位址")]

public

string ip

}//////

全域性搜尋的標記特性

/// public

class

globalserachattribute : attribute

我想要對這些屬性進行乙個綜合的查詢

那麼不可能來乙個需求我就寫乙個where吧,這樣並不符合封裝的思想,所以我需要做的就是尋找共同點,進行封裝

public

static

class

baseserach

), expression.constant(str));

exps.add(expression.andalso(exp1, exp2));

});return ienumerables.where(getlambda());

}//////

獲取表示式

/// ///

///private

static funcbool> getlambda()

where t : class

if (whereexpr == null

)

return

null

;

return expression.lambdabool>>(whereexpr, m_parameter).compile();}}

這裡的方法就可以用來進行泛型的普遍屬性檢索,

呼叫起來也很簡單

var beforelist = new list() ,new serachentity()  };

var lastlist = beforelist.wherebyglobalserach("

餘");

我感覺這就是特性最好用的一點了,用於標記。

c 之Attribute特性的原理

當我們在visual studio新增乙個自定義控制項時,它都會給我們以下預設的 defaultproperty text toolboxdata webcustomcontrol1 runat server public class webcustomcontrol1 webcontrol set...

C 特性Attribute學習

起初一直糾結於如何呼叫特性附著在下面那個成員的值,後來發現不需要呼叫,通過反射載入的時候是自動繫結上去的,即 獲得成員物件之後,有乙個方法可以獲得特性標籤。其實從類庫提供者,和類庫使用者的角度,分開來看就很容易理解了。類庫提供者 myclasslib類 myclasslib類有乙個showstrin...

C 特性Attribute學習

起初一直糾結於如何呼叫特性附著在下面那個成員的值,後來發現不需要呼叫,通過反射載入的時候是自動繫結上去的,即 獲得成員物件之後,有乙個方法可以獲得特性標籤。其實從類庫提供者,和類庫使用者的角度,分開來看就很容易理解了。類庫提供者 myclasslib類 myclasslib類有乙個showstrin...