C#中的 Attribute 與 Python/TypeScript 中的裝飾器是同個東西嗎

前言

最近成功把「前端帶師」帶入C#的坑(實際是前端帶師開始從cocos轉unity游戲開發了)

某天,「前端帶師」看到這段代碼后問了個問題:[這個是裝飾器]?

[HttpGet]
public?Response?Get()?{return?...
}

我第一反應覺得不是,這玩意在C#中叫“特性”(英文名Attribute,下文統稱為特性),在Java中叫注解,雖然寫法和Python/TypeScript中的差不多,但印象中實現方式應該是不同的。

但咱學理工科的就是要嚴謹,不能僅憑經驗和感覺,為此,我查了一下資料,看了之前楊旭大佬推薦的《C# in nutshell》這本書,不僅確認了這個問題的答案,也對Attribute有了更多了解。

關于AOP

“特性”、裝飾器,其實都是設計模式中的裝飾器模式,同時也是AOP思想。

AOP是Aspect Oriented Programming,即面向切面編程。

AOP把系統分解為不同的關注點,或者稱之為切面(Aspect),是一種在運行時,動態地將代碼切入到類的指定方法、指定位置上的編程思想

比如現在有一個網站,有購物、社交、游戲等多種功能且對所有用戶開放,現在需要限制只有高級會員才能使用其中的幾個功能,我們可以在每個模塊加上if判斷,但這樣侵入性太強,且會造成大量重復代碼;換成AOP的方法就是使用裝飾器,在需要高級會員的地方加上限制就行~

具體的區別

先來看看語法上的不同

Python的裝飾器

先來看看Python中的裝飾器,在Python中函數是一等公民,裝飾器也是個函數,其內部又內嵌了另一個函數

def?outer(func):def?inner():#?...?一些代碼result?=?func()return?resultreturn?inner

使用的時候

@outer
def?test():print('test')

使用時語法和Java的注解一樣,以@開頭

其實這是個語法糖,實際的效果等同于

outer(test)

test函數作為參數傳入給裝飾器,之后這段代碼的執行順序如下:

  • def outer(func):裝飾器定義

  • @outer:裝飾器語法糖,直接直接執行outer函數,將test函數作為參數傳入

  • outer:執行裝飾器語法規則,將test函數替換成inner函數

  • inner:執行inner函數代碼

  • test:根據inner中的這行代碼:result = func(),執行test函數代碼

  • 返回

在Python這種動態語言中,實現裝飾器模式確實是比靜態語言容易的,被裝飾的內容作為參數傳入裝飾器,裝飾器可以直接訪問到被裝飾的內容進行一些處理。

C#的“特性”

C#中,“特性”是一個類,繼承自Attribute類,然后可以包含任意你想要的屬性字段

AttributeUsage特性修飾,可以指定該特性可以修飾哪些代碼元素

[AttributeUsage(AttributeTargets.Class?|
AttributeTargets.Constructor?|
AttributeTargets.Field?|
AttributeTargets.Method?|
AttributeTargets.Property,
AllowMultiple?=?true)]
public?class?DemoAttribute?:?Attribute?{public?DemoAttribute(string?param1)?{this.param1?=?param1;}public?string?param1?{?get;?set;?}
}

構造方法中的參數,就是使用特性時傳入的參數,比如這樣:

[DemoAttribute("class")]
public?class?DemoClass?{[Demo("method")]public?void?Method1()?{}
}

PS:特性使用時可以省略后面的"Attribute",所以DemoAttributeDemo是同個東西

這樣寫了之后并不會產生什么效果

因為特性只是單純的裝飾

在代碼運行的時候,C#編譯器先實例化DemoAttribute這個類,然后再實例化DemoClass這個類,且在DemoAttribute內是無法獲取到被裝飾的內容的。

為了使裝飾起效果,需要搭配使用反射~

反射指程序可以訪問、檢測和修改它本身狀態或行為的一種能力。

通過下面的代碼可以獲取到裝飾在DemoClass上的特性

var?info?=?typeof(DemoClass);
var?attributes?=?info.GetCustomAttributes(true);

通過下面的代碼可以獲取被裝飾的方法,和裝飾參數啥的

foreach?(var?methodInfo?in?typeof(DemoClass).GetMethods())?{var?attribute?=?(DemoAttribute)?Attribute.GetCustomAttribute(methodInfo,?typeof(DemoAttribute));if?(attribute?!=?null)Console.WriteLine("方法?{0}?被裝飾,裝飾參數?{1}",?methodInfo.Name,?attribute.param1);
}

獲取到這些信息后,通過反射提供的其他功能再進行一些處理,也就實現了所謂的AOP

小結

所以,C#的特性和Python/TypeScript中的裝飾器,雖然寫法用法不一樣,但殊途同歸,要實現的目的確實是差不多的。

但要說是同樣的東西又不嚴謹,所以應該同樣的東西,不過都是各自語言中實現AOP的方式。

參考資料

  • C#的Attribute和Typescript的裝飾器之比較:https://blog.csdn.net/weixin_43263355/article/details/110137016

  • C#中如何實現類似Python中的裝飾器:https://www.zhihu.com/question/36211661

  • AOP面向切面編程:https://bbs.huaweicloud.com/blogs/289045

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/285520.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/285520.shtml
英文地址,請注明出處:http://en.pswp.cn/news/285520.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【ArcGIS Engine二次開發】入門基礎(1):ArcGIS Engine簡介及開發環境搭建

文章目錄ArcGIS Engine概述ArcGIS Engine與ArcObjects的關系ArcGIS Engine下載及安裝ArcGIS Engine概述 ArcGIS Engine簡介 ArcGIS Engine是ESRI公司在2004年推出的用于開發C/S架構GIS應用軟件的工具包,是將用于構建ArcGIS整套產品的組件庫——ArcObjects的比分功…

微軟Visual Studio 2019版本16.3 正式發布,支持 .NET Core 3.0

微軟正式發布了Visual Studio 2019 16.3版本,主要更新內容如下: .NET Core 3.0 Visual Studio版本16.3包括對 .NET Core 3.0 的支持。 注意:如果使用的是.NET Core 3.0,則需要使用Visual Studio 16.3或更高版本。 .NET Core桌…

C語言試題120之輸入兩個正整數 m 和 n,求其最大公約數和最小公倍數

?作者簡介:大家好我是碼莎拉蒂,CSDN博客專家?????? ??個人主頁:個人主頁 ??系列專欄:C語言試題200例 ??推薦一款模擬面試、刷題神器?? 點擊跳轉進入網站 1、題目 題目:輸入兩個正整數 m 和 n,求其最大公約數和最小公倍數 分析:利用輾除法 2 、溫馨提示…

spring+springMvc+mybatis 調用oracle 存儲過程

最近在項目中遇到在mybatis中調用oracle存儲過程的問題,網上各種查詢,最終解決了問題,在我們項目中我只需要oracle 的存儲過程返回一個字符串用來存入數據庫作為表數據的主鍵, 接下來整理代碼: 首先構建存儲過程getSeq…

OSChina 周一亂彈 ——致我們終將逝去的青春

2019獨角獸企業重金招聘Python工程師標準>>> 我們的青春是這樣的。 從幼兒園午睡開始, 做了一萬遍的廣播體操, 一條充滿了“血”和“淚”的三八線 遍地開花的煎餅果子攤 五毛錢只能養活三天的小雞 象征著財富和地位的彈珠 放學后 奔向世界 放…

【ArcGIS Engine二次開發】入門基礎(2):ArcGIS開發方式(VBA、DLL、Add-in、Engine)對比

文章目錄2.1 使用VBA進行桌面軟件開發2.1.1 VBA開發方式2.1.1 VBA代碼的安全性2.2 使用DLL進行桌面軟件開發2.2.1 DLL開發方式2.2.2 DLL功能的應用部署2.3 使用Add-in進行桌面軟件開發2.4 使用ArcGIS Engine構建獨立應用程序對于桌面GIS應用來說,ArcGIS平臺不僅提供…

使用.Net驅動Jetson Nano的OLED顯示屏

背景最近幾年,邊緣計算的需求急劇爆發。人工智能、物聯網和 5G 的演進給邊緣計算帶來了無限的可能性。因為工作原因,有幸在2019開始接觸了英偉達 Jetson 家族的各種邊緣計算設備:Nano,TX2,AGX,NX等&#xf…

工程測量不用愁,120個視頻動畫幫你忙,簡單易學直觀明了!

工程測量不用愁,120個視頻動畫幫你忙,簡單易學直觀明了!文末提供下載地址。

2016-2017-2學期《程序設計與數據結構》教學進程

2016-2017-2學期《程序設計與數據結構》教學進程 目錄 考核方式課前準備教學進程 第00周學習任務和要求第01周學習任務和要求第02周學習任務和要求第03周學習任務和要求第04周學習任務和要求第05周學習任務和要求第06周學習任務和要求第07周學習任務和要求第08周學習任務和要求…

[轉]Spring SpringMVC SpringBoot SpringCloud概念、關系及區別

一、正面解讀: Spring主要是基于IOC反轉Beans管理Bean類,主要依存于SSH框架(StrutsSpringHibernate)這個MVC框架,所以定位很明確,Struts主要負責表示層的顯示,Spring利…

C語言試題121之輸入一行字符,分別統計出其中英文字母、空格、數字和其它字符的個數。

?作者簡介:大家好我是碼莎拉蒂,CSDN博客專家?????? ??個人主頁:個人主頁 ??系列專欄:C語言試題200例 ??推薦一款模擬面試、刷題神器?? 點擊跳轉進入網站 1、題目 題目:輸入一行字符,分別統計出其中英文字母、空格、數字和其它字符的個數。 分析:利用 w…

5.4 Spring AOP

2019獨角獸企業重金招聘Python工程師標準>>> 5.4.1 從代理機制初探AOP 來看一個簡單的例子,當需要在執行某些方法時留下日志信息,可能會這樣寫: import java.util.logging.*; public class HelloSpeaker{ pirvate Logger loggerL…

WPF 實現心電圖曲線繪制

本文經原作者授權以原創方式二次分享,歡迎轉載、分享。原文作者:流浪g原文地址:https://www.cnblogs.com/cong2312/p/16411637.html一、前言項目中之前涉及到胎兒心率圖曲線的繪制,最近項目中還需要添加心電曲線和血樣曲線的繪制功…

C語言試題110之利用條件運算符的嵌套來完成此題:學習成績大于等于90分的同學用 A 表示,60到89 分之間的用 B 表示, 60 分以下的用 C 表示。

?作者簡介:大家好我是碼莎拉蒂,CSDN博客專家?????? ??個人主頁:個人主頁 ??系列專欄:C語言試題200例 ??推薦一款模擬面試、刷題神器?? 點擊跳轉進入網站 1、題目 題目:C語言試題110之利用條件運算符的嵌套來完成此題:學習成績大于等于90分的同學用 A 表…

【NOIp 2015】【DFS】斗地主

題面 自己網上去搜吧… 代碼 #include <cstdio> #include <cstring> #include <algorithm> #define INF 10000000 #define maxn 40 using namespace std;int t,n,temp,a,zhang[maxn],ansINF;void dfs(int,int,int,int); void shunzi(int,int,int,int,int);vo…

[轉]從入門到精通,Java學習路線導航

引言 最近也有很多人來向我"請教"&#xff0c;他們大都是一些剛入門的新手&#xff0c;還不了解這個行業&#xff0c;也不知道從何學起&#xff0c;開始的時候非常迷茫&#xff0c;實在是每天回復很多人也很麻煩&#xff0c;所以在這里統一作個回復吧。 Java學習路線…

如何讓 Dapper 支持 DateOnly 類型

前言在上次的文章中&#xff0c;我們讓 EF Core 6 支持了 DateOnly 類型。那么&#xff0c;Dapper 是否支持 DateOnly 類型呢&#xff1f;public class User {public int Id { get; set; }public string Name { get; set; }public DateOnly Birthday { get; set; } }using (var…

HP proliant服務器從usb啟動

1&#xff0c;開機出現自檢畫面開始按F9進入設置&#xff0c;進入BIOS 選擇standard boot order&#xff08;rpl&#xff09;&#xff0c;把usb driver放在第一位&#xff0c;保存好 2&#xff0c;按F1開始啟動。 &#xff08;注&#xff1a;我使用ubuntu14.04&#xff0c;到啟…

VB常用內部函數大全一覽表(建議收藏)

VB提供了大量的內部函數供用戶在編程時調用。內部函數按其功能分為數學運算函數、字符串函數、轉換函數、日期與時間函數、判斷函數和格式輸出函數等。 文章目錄 算術函數字符串函數日期和時間函數數據類型轉換函數算術函數 字符串函數 日期和時間函數

數據庫分類介紹

在當今的互聯網中&#xff0c;最常見的數據庫模型主要是兩種&#xff0c;即“關系型數據庫”和“非關系型數據庫”。 一、關系型數據庫 1、關系型數據庫的由來 雖然網狀數據庫和層次數據庫已經很好的解決了數據的集中和共享問題&#xff0c;但是在數據庫獨立性和抽象級別上扔有…