C#特性與反射知識梳理

C#中的**特性(Attributes)反射(Reflection)**是兩個非常重要的概念,它們通常用于代碼的元編程,允許你在運行時獲取類型信息并對其進行操作。下面對這兩個概念進行詳細梳理:

一、C#中的特性(Attributes)

特性是C#中的一種機制,允許你為類、方法、屬性、字段、參數等代碼元素添加額外的元數據。特性可以在編譯時進行檢查,也可以在運行時通過反射獲取。

1. 特性的定義

特性是從 System.Attribute 基類派生的類。例如:

csharp

復制編輯

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)] public class MyCustomAttribute : Attribute { public string Name { get; set; } public MyCustomAttribute(string name) { Name = name; } }

在上面的代碼中,MyCustomAttribute 是一個自定義特性,AttributeUsage 特性指定了它可以應用到類和方法上。

2. 特性的使用

定義了特性后,可以像下面這樣將它應用到代碼中的某個元素:

csharp

復制編輯

[MyCustomAttribute("Example")] public class MyClass { [MyCustomAttribute("Method Example")] public void MyMethod() { } }

在這個例子中,MyCustomAttribute 被應用到類 MyClass 和它的 MyMethod 方法上。

3. 獲取特性

可以使用反射來獲取應用于類型或成員的特性。例如:

csharp

復制編輯

var type = typeof(MyClass); var method = type.GetMethod("MyMethod"); var classAttribute = (MyCustomAttribute)Attribute.GetCustomAttribute(type, typeof(MyCustomAttribute)); var methodAttribute = (MyCustomAttribute)Attribute.GetCustomAttribute(method, typeof(MyCustomAttribute)); Console.WriteLine(classAttribute.Name); // Output: Example Console.WriteLine(methodAttribute.Name); // Output: Method Example

4. 特性的常見用途
  • 標記和文檔化:例如,[Obsolete][Serializable] 等特性,用于標記類或方法。

  • 自定義驗證和授權:如 [Authorize] 特性用于身份驗證。

  • 數據映射:比如在ORM框架(如Entity Framework)中使用特性來映射數據庫表和字段。

  • 代碼生成:某些框架或工具使用特性來自動生成代碼。

二、C#中的反射(Reflection)

反射是指在運行時檢查和操作類型、方法、屬性、字段等的能力。反射可以用于獲取類型信息、動態創建對象、調用方法、訪問字段等。

1. 獲取類型信息

反射提供了 Type 類來獲取對象的類型信息。例如:

csharp

復制編輯

Type type = typeof(MyClass); // 獲取類型信息 Console.WriteLine(type.FullName); // 輸出類的完整名稱

如果你有一個對象實例,也可以通過 .GetType() 獲取其類型:

csharp

復制編輯

MyClass obj = new MyClass(); Type type = obj.GetType(); Console.WriteLine(type.FullName);

2. 獲取和操作成員信息

可以使用反射獲取類型的構造函數、方法、字段、屬性等信息:

csharp

復制編輯

var methodInfo = type.GetMethod("MyMethod"); methodInfo.Invoke(obj, null); // 調用MyMethod

獲取字段:

csharp

復制編輯

var fieldInfo = type.GetField("myField"); fieldInfo.SetValue(obj, 42); // 設置字段值 Console.WriteLine(fieldInfo.GetValue(obj)); // 獲取字段值

獲取屬性:

csharp

復制編輯

var propertyInfo = type.GetProperty("MyProperty"); propertyInfo.SetValue(obj, "New Value"); Console.WriteLine(propertyInfo.GetValue(obj));

3. 動態創建實例

反射可以動態創建對象:

csharp

復制編輯

var constructor = type.GetConstructor(Type.EmptyTypes); var instance = constructor.Invoke(null);

4. 動態方法調用

通過反射可以動態調用方法,無論是實例方法還是靜態方法:

csharp

復制編輯

var method = type.GetMethod("MyMethod"); method.Invoke(obj, new object[] { param1, param2 });

5. 使用反射獲取特性

反射也可以用來獲取與某個成員相關的特性:

csharp

復制編輯

var attributes = type.GetCustomAttributes(typeof(MyCustomAttribute), false); foreach (var attribute in attributes) { Console.WriteLine(((MyCustomAttribute)attribute).Name); }

三、特性與反射的結合

反射和特性通常是結合使用的。在實際應用中,特性可以用于標記代碼的某些元數據,而反射則可用于在運行時讀取這些信息。例如,在自定義的ORM框架中,可以通過特性來標記類和字段與數據庫的映射關系,然后通過反射在運行時自動構建數據庫查詢。

例如,假設你有如下的特性:

csharp

復制編輯

[AttributeUsage(AttributeTargets.Property)] public class ColumnAttribute : Attribute { public string ColumnName { get; } public ColumnAttribute(string columnName) { ColumnName = columnName; } }

你可以用它標記類的屬性:

csharp

復制編輯

public class Person { [Column("person_name")] public string Name { get; set; } [Column("person_age")] public int Age { get; set; } }

然后通過反射來讀取特性并生成SQL查詢:

csharp

復制編輯

Type type = typeof(Person); var properties = type.GetProperties(); foreach (var property in properties) { var columnAttribute = (ColumnAttribute)Attribute.GetCustomAttribute(property, typeof(ColumnAttribute)); if (columnAttribute != null) { Console.WriteLine($"Property: {property.Name}, Column: {columnAttribute.ColumnName}"); } }

四、反射的性能問題

反射的一個重要缺點是性能開銷較大,特別是在頻繁使用反射時。如果你的應用程序對性能要求非常高,盡量減少反射的使用,或考慮使用其他優化方式(如緩存反射信息)。

總結

  • 特性(Attributes):用于給代碼元素(如類、方法、屬性等)添加元數據,通常在運行時獲取這些元數據。

  • 反射(Reflection):用于在運行時獲取類型信息并動態操作對象,可以動態創建對象、調用方法、訪問字段等。

  • 結合使用:通過反射獲取和處理特性,能夠讓程序在運行時更加靈活、可擴展。

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

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

相關文章

SQL 語法詳解

SQL 語法詳解 引言 SQL(Structured Query Language)是一種用于數據庫管理的標準語言,它允許用戶進行數據的查詢、更新、插入和刪除等操作。SQL語法是數據庫管理和編程的基礎,本篇文章將詳細介紹SQL的基本語法和常用操作&#xff0…

為什么 sim(3) 中的尺度 s 與旋轉 R 相乘,而不是平移 t?

文章目錄為什么 sim(3) 中的尺度 s 與旋轉 R 相乘,而不是平移 t?1?? sim(3) vs SE(3):結構對比與核心差異2?? 為什么尺度 s 不乘在 t 上?🚫 數學破壞:🧭 幾何解釋:3?? t 是“相…

如何為你的 Docker 容器設置代理網絡

一文搞定!如何為你的 Docker 容器設置代理網絡(及一個最常見的“坑”) 你是否遇到過這樣的窘境:在你的服務器上,代理工具(比如 Clash, V2Ray)運行得好好的,瀏覽器也能科學上網,但一旦把應用放進 Docker 容器,它就瞬間“失聯”,無法訪問外部世界? 別擔心,這是每個…

LeetCode Day3 -- 哈希表

目錄 1. 啥是哈希表? 2. 啥時候用哈希表? 2.1 存在性檢查 → 集合Set 2.2 鍵值映射 → 字典Dict 2.3 頻率統計 → Dict or Counter 3. LeetCode 3.1 集合 (1)2215 找出兩數組的不同 (2)1207 獨一無…

三子棋裝置(電賽24E題)K230/STM32全開源

三子棋裝置(電賽24E題)K230/STM32全開源,后續有具體代碼參數講解,幫助大家移植k230代碼import time, os, sysfrom media.sensor import * from media.display import * from media.media import *from machine import UART from m…

終端安全檢測與防御

1. 終端安全風險主要問題:企業網絡中80%的安全事件源于終端,終端成為黑客攻擊的重要目標。攻擊手段:勒索病毒:直接勒索用戶。橫向滲透:通過受控終端攻擊內部服務器。僵尸網絡危害:信息竊取、釣魚網站引導、…

Video_AVI_Packet(2)

博主聲明:內容來自網絡,僅供參考,僅適用于淺了解,如有錯誤,自行甄別,由此引起的后果概不負責 Video_AVI_Packet(2)一、Video Picture Aspect Ratio 與 Active Format Aspect Ratio1.…

八月補丁星期二:微軟修復 111 個漏洞

微軟將在2025 年 8 月補丁星期二修復 111 個漏洞,這一數量與近期平均水平大致相同。 與上個月的情況類似,微軟知道今天發布的漏洞中只有一個已被公開披露,但聲稱沒有證據表明存在野外利用。同樣,截至發布時,唯一的補丁…

《C++進階之繼承多態》【普通類/模板類的繼承 + 父類子類的轉換 + 繼承的作用域 + 子類的默認成員函數】

【普通類/模板類的繼承 父類&子類的轉換 繼承的作用域 子類的默認構造函數】目錄前言:------------------------一、繼承的定義和使用1. 什么使繼承?2. 為什么要引入繼承?3. 怎么使用繼承?① 父類(基類&#xf…

Ubuntu22.04安裝OBS Studio

OBS官網的最新的雖然支持Ubuntu系統,但是只支持最新的24.2版本的,而我的電腦上的Ubuntu的版本是22.04,所以在網上尋求解決辦法,看到了這一片博客,作為參考來實現ubuntu22.04安裝OBS,這里提示一下&#xff0…

Ansible 基本使用

Ansible 清單 靜態主機清單 主機清單支持多種格式,例如ini、yaml、腳本等。 本次課程使用 ini 格式。 #創建主機清單[lykcontroller ~ 13:36:01]# vim inventory#vim添加controllernode1node2node3node4?#測試連接單個服務器[lykcontroller ~ 14:08:18]$ ansibl…

網絡資源模板--基于Android Studio 實現的九寨溝App

目錄 一、測試環境說明 二、項目簡介 三、項目演示 四、部設計詳情(部分) 首頁 購票頁面 五、項目源碼 一、測試環境說明 電腦環境 Windows 11 編寫語言 JAVA 開發軟件 Android Studio (2020) 開發軟件只要大于等于測試版本即可(近幾年官網直接下載也…

系統架構設計師備考之架構設計實踐知識

1.信息系統架構設計理論與實踐1.1.基本概念信息系統架構定義目前關于信息系統架構較為權威的定義有: (1)信息系統架構是系統的結構,由軟件元素、元素外部可見屬性和元素間關系組成。 (2)信息系統架構是軟件…

【IgH EtherCAT】如何利用 RTAI 提供的實時任務和調度機制來構建一個高精度、確定性的工業控制應用

SVG圖展示了系統的分層架構:RTAI實時層:包含RT_TASK、信號量和定時器EtherCAT Master層:主站、域、從站配置和PDO映射EtherCAT網絡層:與實際硬件設備(EL3162模擬輸入、EL2004數字輸出)通信關鍵特點&#xf…

7款熱門智能電視文件管理器橫向評測

7款智能電視文件管理器橫向評測 在智能電視和電視盒子日益普及的今天,一款好用的文件管理器能讓您的數字生活更加便捷。本文為您評測了7款廣受歡迎的TV版文件管理器,助您找到最適合自己的工具。 1. ES文件瀏覽器TV版 ES文件瀏覽器是一款廣受歡迎的多功能…

Python 類元編程(導入時和運行時比較)

導入時和運行時比較 為了正確地做元編程,你必須知道 Python 解釋器什么時候計算各個代碼 塊。Python 程序員會區分“導入時”和“運行時”,不過這兩個術語沒有嚴 格的定義,而且二者之間存在著灰色地帶。在導入時,解釋器會從上到 下…

[git diff] 對比檢查變更 | 提交前復審 | 版本回退

git diff git diff 是 Git 版本控制系統中用于比較文件差異的核心命令,可以顯示工作目錄、暫存區(Index)和倉庫歷史之間的變化。 通過對比不同版本或狀態的文件內容,幫助開發者理解代碼變更。 比較工作目錄與暫存區 運行以下命令查…

【數據可視化-85】海底撈門店數據分析與可視化:Python + pyecharts打造炫酷暗黑主題大屏

🧑 博主簡介:曾任某智慧城市類企業算法總監,目前在美國市場的物流公司從事高級算法工程師一職,深耕人工智能領域,精通python數據挖掘、可視化、機器學習等,發表過AI相關的專利并多次在AI類比賽中獲獎。CSDN…

物聯網之小白調試網關設備

小伙伴們,你們好呀!我是老寇!跟我一起學習調試網關設備 相信搞過物聯網的朋友,對網關設備非常熟悉,本人以小白的視角,手把手教你調試網關設備! 工作中使用的是Ubuntu操作系統,因此&a…

Node.js特訓專欄-實戰進階:22. Docker容器化部署

?? 歡迎來到 Node.js 實戰專欄!在這里,每一行代碼都是解鎖高性能應用的鑰匙,讓我們一起開啟 Node.js 的奇妙開發之旅! Node.js 特訓專欄主頁 專欄內容規劃詳情 我將從Docker容器化部署的基礎概念入手,介紹Node.js應用容器化的步驟,包括創建Dockerfile、構建鏡像、運行…