首页 > 编程语言 >c#中的特性Atrtribute和反射

c#中的特性Atrtribute和反射

时间:2023-05-03 10:22:39浏览次数:33  
标签:反射 自定义 c# Attribute Atrtribute 特性 实例 类型 Type

特性(Attribute)

特性概述

特性即 Attribute ,网页翻译也叫属性。他在c#代码中是一个类,名称通常为 xxxAttribute 。用于对程序片段(方法、类、属性)等附加一些额外信息,这些信息可以通过反射被获取,以便做一些逻辑处理。通常与筛选器、AOP等结合使用。

官方文档:利用特性扩展元数据 | Microsoft Learn

Attribute与注释的区别

注释是对程序源代码的一种说明,主要目的是给人看的,在程序被编译的时候会被编译器所丢弃,因此,它丝毫不会影响到程序的执行。

Attribute是程序代码的一部分,它不但不会被编译器丢弃,而且还会被编译器编译进程序集(Assembly)的元数据(Metadata)里。.NET中元数据是指程序集中的命名空间、类、方法、属性等信息。在程序运行的时候,随时可以通过反射(Reflection)从元数据中提取出这些附加信息,并以之决策程序的运行。

如何自定义特性

Attribute 类

自定义特性即自定义一个继承自 System.Attribute 的类,并且类名要以Attribute结尾,安全起见,建议对类用Sealed修饰。

当我们为目标(类|方法|属性等)应用特性时,其实是在指定应该是用哪个构造函数来创建特性的实例。列在特性中的参数其实就是其构造函数的参数。如果应用的特性的构造函数没参数,可以省略括号。

使用形式上即:[特性名(参数列表)]就是有点像调用构造函数那样,只不过两边加了中括号,而且无参时可以只要特性名。特性名用类名,或者类名去掉Attribute的部分。形式如下:

//加入已经预先定义好了一个ConditionalAttribute特性。

//长记法
[ConditionalAttribute("Li")]
[ConditionalAttribute("NoBug")]
public static void Func()
{Console.WriteLine("Created by Li, NoBug"); }
//短记法
[Conditional("Li")]
[Conditional("NoBug")]
public static void Func()
{Console.WriteLine("Created by Li, NoBug"); }
//换序
[Conditional("NoBug")]
[Conditional("Li")]
public static void Func()
{Console.WriteLine("Created by Li, NoBug"); }
//单括号叠加
[Conditional("NoBug"),Conditional("Li")]
public static void Func()
{Console.WriteLine("Created by Li, NoBug"); }

AttributeUsage 类

该特性在自定义特性(类)时使用,用于限制自定义特性的目标类型(即可以对谁使用)。其有三个重要属性:

  • ValidOn:规定自定义特性可对谁使用。用AttributeTarget枚举类型赋值。

  • Inherited:指示特性是否会应用到被装饰类型的子类。Bool类型;

  • AllowMutiple:指示目标是否会被应用多个特性的实例。Bool类型,默认false;

该特性有一个重要的构造函数,接受单个AttibuteTarget枚举类型位置参数,用此参数设置ValidOn字段。

获取一个类中有哪些特性,用到Type类的两个方法:

IsDefined和GetCustomAttributes。前者返回bool型,后者返回object [ ] .

具体如何自定义特性,参考:

C# 特性(Attribute) - 智者见智 - 博客园 (cnblogs.com)

编写自定义特性 | Microsoft Learn

一些.net预设的特性

ObsoleteAttribute

用来指定类的成员或方法已经过时,在程序使用这个成员的时候会给出提示,默认是编译警告。

关于还有哪些预设的特性,如果有哪位网友有相关文章推荐,或晓得官方文档介绍地址,还请评论里留言下,不胜感激。

特性相关概念或知识

  • 反射(Reflection)技术
  • 筛选器
  • AOP

反射(Reflection)技术

反射是什么

通常,反射用于动态获取对象的类型、属性和方法等信息,反射机制允许程序在执行过程中动态地添加各种功能。

c#中,通过 is 、 as 、typeof 这三个关键字可以在程序执行期间判定对象类型

is 运算符:判断两个类型或对象实例是否兼容

bool res= A is B;

A和B是某个类型或某个类型的实例。如果A是B的一个实例,或者A继承自B,则结果res为true,否则为false。通常 is 运算符检验两个类型是否可以转换。

as 运算符:不会抛异常的类型转换

var res= A as B;

A和B是某个类型或某个类型的实例。如果A是B的一个实例,或者A继承自B,则结果res为B类型的一个实例,否则为null。as 运算符在运行期间执行类型转换,并且能够使得类型转换失败不抛异常,而返回一个null值

typeof 方法:

var res= typeof (a) ;

a是某个类型的一个实例对象。typeof 可以返回与具体类型相关的System.Type对象,一旦获得给定类型的Type对象,就可以通过使用该对象(res)定义的各种属性,字段,方法来获取类型 (a) 的具体信息,比如 a 的属性,方法等。

反射的核心类:System.Type

程序在运行时,可以查看其它程序集或其本身的元数据 ,一个运行的程序查看本身的元数据或其它程序的元数据的行为叫反射。我们使用Type类来反射数据,要用到System.Reflection命名空间。

Type是抽象类,派生于System.Reflection.MemberInfo抽象类。在运行时,CLR创建从Type( Runtim Type )派生的类的实例,Type包含了类型信息。有关Type的重要事项:

a) 对于程序中用到的每一个类型,CLR都会创建一个包含这个类型信息的Type类型的对象。

b) 程序中用到的每一个类型都会关联到独立的Type类的对象。

c) 不管创建的类型 有多少个实例,只有一个Type类型对象会关联到所有这些实例。

我们可以从Type对象获取需要了解的有关类型的几乎所有信息。

获取Type对象的两种方式

  • Type t = 类实例 . GetType ( ) ;

  • Type t = typeof ( 类实例名 );


更新于:2023-05-03

标签:反射,自定义,c#,Attribute,Atrtribute,特性,实例,类型,Type
From: https://www.cnblogs.com/idasheng/p/17368737.html

相关文章

  • 使用docker部署nginx并配置https
     #安装dockerpullnginx​#安装后查看docker镜像dockerimages安装就只需要一个命令,连安装包都不用自己找,这就是我用docker的原因。建目录用于存放nginx配置文件、证书文件:mkdir/opt/docker/nginx/conf.d-pmkdir/opt/docker/nginx/cert-pnginx的ssl证书长这个样子,两......
  • cublas runtime error : the GPU program failed to execute 报错
    情景在使用pytorch1.0和RTX3060Laptop训练GIN的时候出现了这个错误原因pytorch1.0对应的cuda10.0版本太低了,不支持新的GPU架构解决最终使用了更新版本的pytorch......
  • dockerfile概念简介——镜像分层
    一、dockerfile概念dockerfile是自定义镜像的一套规则dockerfile由多条指令构成,Dockerfile中的每一条指令都会对应于Docker镜像中的每一层1.1docker镜像的分层dockerfile的原理就是镜像分层。Dockerfile中的每个指令都会创建一个新的镜像层(是一个临时的容器,执行完后......
  • c#归并排序
    voidMergeSort(int[]arr){intl=0;intr=arr.Length-1;MergeSortSub(arr,l,r);}//1,2voidMergeSortSub(int[]arr,intleft,intright){if(left==right)return;intmid=left+((right-left)>>1);MergeSortSub(arr......
  • VS2022使用ClickOnce发布程序本地安装.net框架
    因为遇到下面的错误,没有在网上搜到详细解决问题的教程,费了一些时间才解决了问题,特此记录一下,也希望能帮助到其他人。 要在“系统必备”对话框中启用“从与我的应用程序相同的位置下载系统必备组件”,必须将“.NET桌面运行时6.0.14(x64)”项的文件“net6desktopruntime_x64\win......
  • docker搭建本地私有仓库详细步骤
    1、首先下载registry镜像dockerpullregistry12、在daemon.json文件中添加私有镜像仓库的地址并重启vim/etc/docker/daemon.json{ "insecure-registries":["192.168.59.111:5000"],#添加此段,“,”不可少,ip是本机IP地址 "registry-mirrors":["https://4abdkxlk.mi......
  • docker的资源控制管理——Cgroups
    前言docker使用cgrqup控制资源,K8S里面也有limit(使用上限)docker通过cgroup来控制容器使用的资源配额,包括CPU、内存、磁盘三大方面,基本覆盖了常见的资源配额和使用量控制。Cgroup是Controlgroup的简写,是Linux内核提供的一种限制所使用物理资源的机制,包括CPU、内存......
  • .NET Core部署到linux(CentOS)最全解决方案,入魔篇(使用Docker+Jenkins实现持续集成、
    通过前面三篇:.NETCore部署到linux(CentOS)最全解决方案,常规篇.NETCore部署到linux(CentOS)最全解决方案,进阶篇(Supervisor+Nginx).NETCore部署到linux(CentOS)最全解决方案,高阶篇(Docker+Nginx或Jexus)通过前面三篇文章的介绍,我们已经对.netcore多方案部署到linux下有......
  • React 中 Router的相关面试题
    一、请你说说react的路由是什么?React的路由是纯前端的路由,就是根据hash或browserpath的变化,框架内封装好了方法,可以自由的切换DOM展示,来模拟页面或局部页面被替换的目的;让浏览器不用刷新,也能获取想要的页面结构,保存内存数据,提升用户体验 二、React-Router实现原理?当url发......
  • .NET Core部署到linux(CentOS)最全解决方案,入魔篇(使用Docker+Jenkins实现持续集成、
    通过前面三篇:.NETCore部署到linux(CentOS)最全解决方案,常规篇.NETCore部署到linux(CentOS)最全解决方案,进阶篇(Supervisor+Nginx).NETCore部署到linux(CentOS)最全解决方案,高阶篇(Docker+Nginx或Jexus)通过前面三篇文章的介绍,我们已经对.netcore多方案部署到linux下有......