C#中的Attributes特性創建和結合反射應用舉例

C#中的特性入門學習

Attributes官方介紹概述

Attributes provide a powerful method of associating metadata, or declarative information, with code (assemblies, types, methods, properties, and so forth). After an attribute is associated with a program entity, the attribute can be queried at run time by using a technique called reflection.

Attributes have the following properties:

Attributes add metadata to your program. Metadata is information about the types defined in a program. All .NET assemblies contain a specified set of metadata that describes the types and type members defined in the assembly. You can add custom attributes to specify any additional information that is required.
You can apply one or more attributes to entire assemblies, modules, or smaller program elements such as classes and properties.
Attributes can accept arguments in the same way as methods and properties.
Your program can examine its own metadata or the metadata in other programs by using reflection.
Reflection provides objects (of type Type) that describe assemblies, modules, and types. You can use reflection to dynamically create an instance of a type, bind the type to an existing object, or get the type from an existing object and invoke its methods or access its fields and properties. If you’re using attributes in your code, reflection enables you to access them. For more information, see Attributes.
翻譯出來就是,特性提供了一種將元數據或聲明性信息與代碼(程序集、類型、方法、屬性等)相關聯的強大方法。將屬性與程序實體關聯后,可以使用反射技術在運行時查詢該屬性。

反射可以創建類型對象,比如程序集、模塊。可以使用反射來動態創建類型的實例,將類型綁定到現有對象,或者從現有對象獲取類型并調用其方法或訪問其字段和屬性。如果您在代碼中使用特性,則反射可以訪問它們并做相應的邏輯。
這些可以實現一些靈活多變的應用程序,比如圖形編程,無代碼編程,復雜動態變化實現簡化等。

創建特性

public class AttTestAttribute : Attribute {public string Desc { get; set; }public AttTestAttribute (){Console.WriteLine("AttTestAttribute 無參構造函數");}public AttTestAttribute (string desc) { this.Desc = desc;Console.WriteLine("AttTestAttribute 有參構造函數");}
}

使用范圍

assembly Entire assembly// 程序集
module Current assembly module // 組件
field Field in a class or a struct // 字段
event Event // 事件
method Method or get and set property accessors // 方法
param Method parameters or set property accessor parameters // 方法的參數
property Property // 屬性
return Return value of a method, property indexer, or get property accessor // 方法的返回值
type Struct, class, interface, enum, or delegate // 結構體 接口 枚舉 委托 等

舉例

 [AttTest("我在類上使用")]public class Student {[AttTest("我在字段上使用")]public string name;[AttTest("我在屬性上使用")]public string Name { get { return name; } set { name = value; } }[AttTest("我在方法上使用")][return: AttTest("我在返回值上")]public string GetName([AttTest("參數")] int Id) {return name;}}

獲取這些信息

static void Main(string[] args){Student student=new Student() { Name="小明"};
Console.WriteLine(student.GetName(1));Type type = typeof(Student);
//判斷是否在類上使用特性
if (type.IsDefined(typeof(AttTestAttribute), true))
{AttTestAttribute customAttribute = (AttTestAttribute)type.GetCustomAttribute(typeof(AttTestAttribute), true);Console.WriteLine(customAttribute.Desc);
}MethodInfo method = type.GetMethod("GetName");
//判斷是否在方法上使用特性
if (method.IsDefined(typeof(AttTestAttribute), true))
{AttTestAttribute customAttribute = (AttTestAttribute)method.GetCustomAttribute(typeof(AttTestAttribute), true);Console.WriteLine(customAttribute.Desc);
}ParameterInfo parameter = method.GetParameters()[0];
//判斷是否在參數上使用特性
if (parameter.IsDefined(typeof(AttTestAttribute), true))
{AttTestAttribute customAttribute = (AttTestAttribute)parameter.GetCustomAttributes(typeof(AttTestAttribute), true)[0];Console.WriteLine(customAttribute.Desc);
}ParameterInfo returnParameter = method.ReturnParameter;
//判斷是否在方法的返回值上使用特性
if (returnParameter.IsDefined(typeof(AttTestAttribute), true))
{AttTestAttribute customAttribute = (AttTestAttribute)returnParameter.GetCustomAttribute(typeof(AttTestAttribute), true);Console.WriteLine(customAttribute.Desc);
}PropertyInfo property = type.GetProperty("Name");
//判斷是否在屬性上使用特性
if (property.IsDefined(typeof(AttTestAttribute), true))
{AttTestAttribute customAttribute = (AttTestAttribute)property.GetCustomAttribute(typeof(AttTestAttribute), true);Console.WriteLine(customAttribute.Desc);
}FieldInfo field = type.GetField("name");
//判斷是否在字段上使用特性
if (field.IsDefined(typeof(AttTestAttribute), true))
{AttTestAttribute customAttribute = (AttTestAttribute)field.GetCustomAttribute(typeof(AttTestAttribute), true);Console.WriteLine(customAttribute.Desc);
}Console.ReadKey();}

結果:


```csharp```csharp
小明
AttTestAttribute 有參構造函數
我在類上使用
AttTestAttribute 有參構造函數
我在方法上使用
AttTestAttribute 有參構造函數
參數
AttTestAttribute 有參構造函數
我在返回值上
AttTestAttribute 有參構造函數
我在屬性上使用
AttTestAttribute 有參構造函數
我在字段上使用

常見用途

Common uses for attributes
The following list includes a few of the common uses of attributes in code:

Marking methods using the WebMethod attribute in Web services to indicate that the method should be callable over the SOAP protocol. For more information, see WebMethodAttribute.
Describing how to marshal method parameters when interoperating with native code. For more information, see MarshalAsAttribute.
Describing the COM properties for classes, methods, and interfaces.
Calling unmanaged code using the DllImportAttribute class.
Describing your assembly in terms of title, version, description, or trademark.
Describing which members of a class to serialize for persistence.
Describing how to map between class members and XML nodes for XML serialization.
Describing the security requirements for methods.
Specifying characteristics used to enforce security.
Controlling optimizations by the just-in-time (JIT) compiler so the code remains easy to debug.
Obtaining information about the caller to a method.

使用舉例1用屬性識別方法和參數,用反射調用方法

 var myObject = new MyClass();  var methods = myObject.GetType().GetMethods();  var random = new Random();  var method = methods[random.Next(methods.Length)]; // 隨機選擇一個方法  ,也可以使用特性名稱判斷確定方法var parameters = method.GetParameters();  var paramValues = new object[parameters.Length];  for (int i = 0; i < parameters.Length; i++)  {  var paramType = parameters[i].ParameterType;  if (paramType == typeof(string))  {  paramValues[i] = Path.GetRandomFileName(); // 對于字符串類型,生成一個隨機文件名作為參數值  }  else if (paramType.IsPrimitive || paramType == typeof(decimal))  {  paramValues[i] = Activator.CreateInstance(paramType); // 對于原始類型或decimal類型,創建一個默認值作為參數值  }  else  {  throw new NotSupportedException($"Unsupported parameter type: {paramType}");  }  }  var result = method.Invoke(myObject, paramValues); // 調用方法并獲取其返回結果  Console.WriteLine(result); // 打印方法的返回結果  

或者

public class Program  
{  public static void Main()  {  var myObject = new MyClass();  var methodName = "MyMethod"; // 假設這是你要調用的方法的名稱  var parameterTypes = new Type[] { typeof(string), typeof(int) }; // 假設這是你要調用的方法的參數類型  var parameters = new object[] { "Hello", 42 }; // 假設這是你要調用的方法的參數值  var method = myObject.GetType().GetMethod(methodName, parameterTypes);  var paramExpression = Expression.Constant(parameters);  var methodCallExpression = Expression.Call(method, paramExpression);  var lambdaExpression = Expression.Lambda<Func<object>>(methodCallExpression);  var result = lambdaExpression.Compile().Invoke();  Console.WriteLine(result); // 打印方法的返回結果  }  
}  public class MyClass  
{  public string MyMethod(string message, int number)  {  return message + " " + number.ToString();  }  
}

使用舉例2 使用特性排除某些類成員不參與XML序列化和反序列化

舉例C#使用特性排除某些類成員不參與XML序列化和反序列化(https://blog.csdn.net/gy0124/article/details/134777545?spm=1001.2014.3001.5501)

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

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

相關文章

深入理解Vue.js中的this:解析this關鍵字及其使用場景

在Vue.js中&#xff0c;this 和 that 可能是指向不同對象的兩個變量&#xff0c;或者是在代碼中使用時的錯誤。 this&#xff1a; 在Vue組件中&#xff0c;this 指向當前組件的實例。可以通過 this 訪問組件的屬性和方法。 例如&#xff0c;在Vue組件的 data 屬性中定義了一…

2023年第十屆GIAC全球互聯網架構大會-核心PPT資料下載

一、峰會簡介 談到一個應用&#xff0c;我們首先考慮的是運行這個應用所需要的系統資源。其次&#xff0c;是關于應用自身的架構模式。最后&#xff0c;還需要從軟件工程的不同角度來考慮應用的設計、開發、部署、運維等。架構設計對應用有著深遠的影響&#xff0c;它的好壞決…

Leetcode659. 分割數組為連續子序列

Every day a Leetcode 題目來源&#xff1a;659. 分割數組為連續子序列 解法1&#xff1a;哈希 貪心 定義兩個哈希表&#xff1a; numsCount&#xff1a;統計數組 nums 中各元素出現次數。tailCount&#xff1a;存儲以數字 i 結尾的且符合題意的連續子序列個數。 算法&a…

極兔單號查詢,極兔快遞物流查詢,一鍵篩選出退回件

批量查詢極兔快遞單號的物流信息&#xff0c;一鍵篩選出其中的退回件。 所需工具&#xff1a; 一個【快遞批量查詢高手】軟件 極兔快遞單號若干 操作步驟&#xff1a; 步驟1&#xff1a;運行【快遞批量查詢高手】軟件&#xff0c;并登錄 步驟2&#xff1a;點擊主界面左上角的…

【Bootloader學習理解----跳轉優化異常】

筆者接著來介紹一下Bootloader的跳轉代碼以及優化 1、跳轉代碼理解 跳轉代碼可能要涉及到芯片架構的知識,要跳轉到對應的位置&#xff0c;還要設置相關的SP 堆棧指針&#xff0c;具體可以參考筆者這篇文章BootLoader的理解與實現。 STM32的跳轉代碼如下所示&#xff1a; u32 …

ClickHouse為何如此之快

針對ClickHose為什么很快的問題&#xff0c;基于對ClickHouse的基礎概念之上&#xff0c;一般會回答是因為是列式存儲數據庫&#xff0c;同時也會說是使用了向量化引擎&#xff0c;所以快。上面兩方面的解釋也都能夠站得住腳&#xff0c;但是依然不能夠解釋真正核心的原因。因為…

AI:101-基于深度學習的航空影像中建筑物識別

?? 本文選自專欄:人工智能領域200例教程專欄 從基礎到實踐,深入學習。無論你是初學者還是經驗豐富的老手,對于本專欄案例和項目實踐都有參考學習意義。 ??? 每一個案例都附帶有在本地跑過的核心代碼,詳細講解供大家學習,希望可以幫到大家。歡迎訂閱支持,正在不斷更新…

2023_刷題_二叉樹

文章目錄 書leixingleixing 書 leixing leixing

基于以太坊的智能合約開發Solidity(基礎篇)

參考教程&#xff1a;基于以太坊的智能合約開發教程【Solidity】_嗶哩嗶哩_bilibili 1、第一個程序——Helloworld&#xff1a; //聲明版本號&#xff08;程序中的版本號要和編譯器版本號一致&#xff09; pragma solidity ^0.5.17; //合約 contract HelloWorld {//合約屬性變…

Python軸承故障診斷 (四)基于EMD-CNN的故障分類

目錄 前言 1 經驗模態分解EMD的Python示例 2 軸承故障數據的預處理 2.1 導入數據 2.2 制作數據集和對應標簽 2.3 故障數據的EMD分解可視化 2.4 故障數據的EMD分解預處理 3 基于EMD-CNN的軸承故障診斷分類 3.1 訓練數據、測試數據分組&#xff0c;數據分batch 3.2 定義…

D : DS查找——折半查找求平方根

Description 假定輸入y是整數&#xff0c;我們用折半查找來找這個平方根。在從0到y之間必定有一個取值是y的平方根&#xff0c;如果我們查找的數x比y的平方根小&#xff0c;則x2<y&#xff0c;如果我們查找的數x比y的平方根大&#xff0c;則x2>y&#xff0c;我們可以據此…

stu05-前端的幾種常用開發工具

前端的開發工具有很多&#xff0c;可以說有幾十種&#xff0c;包括記事本都可以作為前端的開發工具。下面推薦的是常用的幾種前端開發工具。 1.DCloud HBuilder&#xff08;輕量級&#xff09; HBuilder是DCloud&#xff08;數字天堂&#xff09;推出的一款支持HTML5的web開發…

硬件開發筆記(十四):RK3568底板電路LVDS模塊、MIPI模塊電路分析、LVDS硬件接口、MIPI硬件接口詳解

若該文為原創文章&#xff0c;轉載請注明原文出處 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/134634186 紅胖子網絡科技博文大全&#xff1a;開發技術集合&#xff08;包含Qt實用技術、樹莓派、三維、OpenCV、OpenGL、ffmpeg、OSG、單片機、軟硬…

linux 關于$-的解釋(帖子搜索合集)

在學習Linux的時候&#xff0c;今天遇到了$-&#xff0c;什么意思呢&#xff1f;網上搜索了一些帖子&#xff1a; 帖子1&#xff1a; linux命令 $- 是什么意思 $- 是什么意思&#xff1f;有什么用&#xff1f;可以判斷什么交互式shell&#xff1f; $-記錄著當前設置的shell…

軟考高級備考-系統架構師(機考后新版教材的備考過程與資料分享)

軟考高級-系統架構設計師 考試復盤1.考試結果2.備考計劃3.個人心得 資料分享 考試復盤 1.考試結果 三科壓線過&#xff0c;真是太太太太太太太幸運了。上天對我如此眷顧&#xff0c;那不得不分享下我的備考過程以及一些備考資料&#xff0c;幫助更多小伙伴通過考試。 2.備考…

time模塊(python)

一.sleep休眠 [rootrhel8 day04]# vim demo01_time.py import time def banzhuan():print("搬磚")time.sleep(3.5) #讓程序休眠3.5秒print("結束")banzhuan()[rootrhel8 day04]# python3 demo01_time.py 搬磚 結束運行時&#xff0c;會發現程序中間暫停…

【3DsMax】制作簡單的骨骼動畫

效果 步驟 首先準備4個板子模型展開放置好 添加一個4段的骨骼 選中其中的一塊板子添加蒙皮命令 在蒙皮的參數面板中&#xff0c;設置每塊板子對應哪塊骨骼 設置好后你可以發現此時就已經可以通過骨骼來控制模型了 接下來就可以制作動畫 點擊左下角“時間配置”按鈕 設置一下動…

HarmonyOS--ArkTS(1)--基本語法(1)

目錄 基本語法概述 聲明式UI描述 自定義組件 創建自定義組件 自定義組件的結構--struct &#xff0c;Component&#xff0c;build()函數 生命周期 基本語法概述 裝飾器&#xff1a; 用于裝飾類、結構、方法以及變量&#xff0c;并賦予其特殊的含義。如上述示例中Entry、C…

VSCode安裝與使用

VS Code 安裝及使用 1、下載 進入VS Code官網&#xff1a;地址&#xff0c;點擊 DownLoad for Windows下載windows版本 注&#xff1a; Stable&#xff1a;穩定版Insiders&#xff1a;內測版 2、安裝 雙擊安裝包&#xff0c;選擇我同意此協議&#xff0c;再點擊下一步 選擇你…

SQL Server查詢計劃(Query Plan)——SQL處理過程

6. 查詢計劃(Query Plan) 6.1. SQL處理過程 就SQL語句的處理過程而言,各關系庫間大同小異,尤其是商業庫之間實現機制和細節差別更小些,其功能及性能支持方面也更加強大和完善。SQL Server作為商業庫中的后起之秀,作為SQL語句處理過程的主要支撐和保障,其優化器及相關機…