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.mzph.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语句处理过程的主要支撑和保障,其优化器及相关机…