【.NET Core】特性(Attribute)详解
【.NET Core】特性(Attribute)详解
文章目录
- 【.NET Core】特性(Attribute)详解
- 一、概述
- 二、编写自定义属性
- 2.1 自定义特性的主要步骤
- 2.2 应用AttributeUsageAttribute
- AttributeTargets 成员
- Inherited属性
- AllowMultiple属性
- 三、声明特性类
- 四、声明构造函数特性类
- 五、声明属性的特性类
- 六、自定义特性示例
- 七、总结
- 八、参考
一、概述
公共语言运行时添加类的关键描述性声明(称为特性),以便批注编程元素(如类型、字段、方法和属性)。编译运行时的代码时,它将被转换为中间语言(MSIL),并和编译器生成的元数据一起放置在可移植可执行文件内。特性使得将额外的描述信息放到可使用运行时反射服务提取的元数据中。当你声明派生自System.Attribute
的特殊类的实例时,编译器会创建特性。
在.NET内置了很多特性,这些特性描述数据序列化、指定用于强制安全性的特性并限制通过实时(JIT)编译器进行优化,来对代码进行调优。
二、编写自定义属性
2.1 自定义特性的主要步骤
- 应用AttributeUsageAttribute
- 声明特性类
- 声明构造函数
- 声明属性
2.2 应用AttributeUsageAttribute
自定义属性声明以System.AttributeUsageAttribute属性开头,定义特性类的一些主要特性。
AttributeUsageAttribute
包含下列三个成员,它们对创建自定义属性非常重要:AttributeTargets
、Inheited
和AllowMultiple
。
AttributeTargets 成员
成员 | 值 | 说明 |
---|---|---|
All | 32767 | 属性可以应用于任何应用程序元素。 |
Assembly | 1 | 属性可应用于程序集。 |
Class | 4 | 属性可应用于类。 |
Constructor | 32 | 属性可应用于构造函数。 |
Delegate | 4096 | 属性可应用于委托。 |
Enum | 16 | 属性可应用于枚举。 |
Event | 512 | 属性可应用于事件。 |
Field | 256 | 属性可应用于字段。 |
GenericParameter | 16384 | 属性可应用于泛型参数。目前,这个属性只能在C#,Micrsoft中间语言(MSIL)和emitted代码中。 |
Interface | 1024 | 属性可应用于接口。 |
Method | 64 | 属性可应用于方法。 |
Module | 2 | 属性可应用于模块。模块指的是可移植的执行文件(.dll或.exe),而不是Visual Basic标准模块。 |
Parameter | 2048 | 属性可应用于参数。 |
Property | 128 | 属性可应用于属性。 |
ReturnValue | 8192 | 属性可应用于返回值。 |
Struct | 8 | 属性可应用于结构;也就是值类型。 |
Inherited属性
AttributeUsageAttribute.Inherited
属性指明要对其应用属性的类的派生类能否继承此属性。此属性使用true
(默认值)或false
标志。
public class MyAttribute : Attribute
{//...
}
[AttributeUsage(AttributeTargets.Method, Inherited = false)]
public class YourAttribute : Attribute
{//...
}
AllowMultiple属性
AttributeUsageAttribute.AllowMultiple
属性指明元素能否包含属性的多个实例。如果设置为true
,则允许多个实例。如设置为false(默认值),那么只允许一个实例。
/// <summary>
/// AllowMultiple =false 不允许多个属性
/// </summary>
[AttributeUsage(AttributeTargets.Method,AllowMultiple =false)]
public class MyAttribute:Attribute
{///方法体
}
/// <summary>
/// AllowMultiple =false 允许多个属性
/// </summary>
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public class MultipleMyAttribute : Attribute
{///方法体
}
当应用这些特性的多个实例时,MyAttribute会生成编译器错误吗。以下代码示例显示MultipleMyAttribute的有效以及MyAttribute无效用法:
public class AttributeService
{// This produces an error.// Duplicates are not allowed.[MyAttribute()][MyAttribute()]public void Get() {}// This is valid.[MultipleMy][MultipleMy]public void Update() { }
}
如果AllowMultiple属性和Inherited属性都设置为true,从另一个类继承的类可以继承一个属性,并具有在同一个子类中应用相同属性的另一个实例。如果AllowMultiple设置为false,则父类中的所有特性的值将被子类中一特性的新实例覆盖。
三、声明特性类
应用AttributeUsageAttribute以后,开始定义属性的细节。特性类的声明类似与传统类的声明。如以下代码所示:
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class,AllowMultiple =false)]
public class MyAttribute:Attribute
{///
}
此特性定义说明了以下几点:
- 特性类必须声明为公共类。
- 按照约定,特性类的名称以单词
Attribute
结束。官方虽然没有要求,但是扔建议执行此约定以保证可读性。应用特性时,可以选择是否包含单词Attribute
。 - 所有特性类必须直接或间接从
System.Attribute
类继承。
四、声明构造函数特性类
和传统类类似,特性是通过构造函数初始化的。下面的代码段阐明了典型的特性构造函数。此公共构造函数采用一个参数,并设置一个等于其值的成员变量。
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class,AllowMultiple =false)]
public class MyAttribute:Attribute
{private string myValue;public MyAttribute(string myValue){this.myValue = myValue;}
}
可以重载此构造函数以适应值的各种组合。如果你还未自定义特性类定义了属性,则在初始化该特性时可以使用命名参数和定位参数的组合。通常情况下,将所有必须的参数定义为定位参数,将所有可选的参数定义为命名参数。在这种情况下,没有必需的参数就无法初始化属性。其他所有参数都是可选参数。
五、声明属性的特性类
如果你想要定义一个命名参数,或者提供一种简单的方法来返回由特性存储的值,请声明属性。应将特性的属性声明为公共实例,此公告实体包含将返回的数据类型的描述。定义将保存属性值的变量,并将此变量与get和set方法相关联。
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class,AllowMultiple =false)]
public class MyAttribute:Attribute
{public string AttributeName {get; set;}
}
六、自定义特性示例
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class,AllowMultiple =false)]
public class MyAttribute:Attribute
{private string author;private DateTime data;private string version;public MyAttribute(string author, DateTime data){this.author = author;this.data = data;}public virtual string Author {get { return author; }}public virtual DateTime Data {get { return data; }}public string Version {get { return version; }set { version = value; }}
}
可以采用以下任意一种方法,调用自定义特性:
public class AttributeService
{[MyAttribute("AuthorName","2023-12-18 15:14:01")]public void Get(){}[MyAttribute("Author2","2023-12-18 16:14:49",Version="v1.0")]public void Update() { }
}
七、总结
特性提供声明式编程能力,但是它们是一种元数据形式的代码,本身并不执行任何操作。可以通过反射来调用特性完成操作。
下一章将详解如何使用反射调用特性。
八、参考
- [利用特性扩展元数据](利用特性扩展元数据 | Microsoft Learn)
- [应用属性](应用特性 - .NET | Microsoft Learn)
- [编写自定义属性](编写自定义特性 - .NET | Microsoft Learn)
相关文章:
【.NET Core】特性(Attribute)详解
【.NET Core】特性(Attribute)详解 文章目录 【.NET Core】特性(Attribute)详解一、概述二、编写自定义属性2.1 自定义特性的主要步骤2.2 应用AttributeUsageAttributeAttributeTargets 成员Inherited属性AllowMultiple属性 三、声…...

【C++】POCO学习总结(十九):哈希、URL、UUID、配置文件、日志配置、动态库加载
【C】郭老二博文之:C目录 1、哈希 1.1 说明 std::map和std::set 的性能是:O(log n) POCO哈希的性能比STL容器更好,大约快两; POCO中对应std::map的是:Poco::HashMap; POCO中对应std::set的是 Poco::Hash…...

1846_安全SPI
Grey 全部学习内容汇总:GitHub - GreyZhang/g_embedded: some embedded basic knowledge. 1846_安全SPI SPI是一种常见的通信方式,在汽车电子中比较常用。但是如果涉及到安全相关的设计,可能得考虑更多。而SPI协议本身没有很好的标准化&am…...
SQL Server ,使用递归查询具有层级关系的数据。
假设我们有一个表格 Employees,其中包含员工的层级关系信息,每一行包括员工的ID、姓名以及上级员工的ID。 下面是一个示例表格及其数据: Employees ---------------------- EmployeeID | Name | ManagerID ---------------------- 1 …...
【参数汇总】mysql服务端/客户端常见优化参数
mysql服务端参数 1、innodb_buffer_pool_size (innodb索引buffer pool缓冲区大小) 默认大小为128M, 官方推荐其配置为系统内存的 50% 到 75% 。 一般innodb_buffer_pool_size要结合以下两个参数来设置: innodb_buffer_pool_ch…...

LeetCode 142. 环形链表 II
给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。 如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整…...

Leetcode刷题笔记题解(C++):224. 基本计算器
思路: step 1:使用栈辅助处理优先级,默认符号为加号。 step 2:遍历字符串,遇到数字,则将连续的数字字符部分转化为int型数字。 step 3:遇到左括号,则将括号后的部分送入递归&#x…...

还在为学MyBatis发愁?史上最全,一篇文章带你学习MyBatis
文章目录 前言一、📖MyBatis简介1.Mybatis历史2.MyBatis特性3.对比(其他持久化层技术) 二、📣搭建MyBatis1.开发环境2.创建maven工程3.创建MyBatis核心配置文件4.创建mapper接口5.创建MyBatis的映射文件6.通过junit测试功能7.加入…...

C# WPF上位机开发(树形控件在地图软件中的应用)
【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 前面我们聊过图形软件的开发方法。实际上,对于绘制的图形,我们一般还会用树形控件管理一下。举个例子,一个地图…...

【华为】文档中命令行约定格式规范(命令行格式规范、命令行行为规范、命令行参数格式、命令行规范)
文章目录 命令行约定格式**粗体:命令行关键字***斜体:命令行参数*[ ]:可选配置{ x | y | ... } 和 [ x | y | ... ]:选项{ x | y | ... }* 和 [ x | y | ... ]*:多选项&<1-n>:重复参数#ÿ…...

Trie 字典树(c++)(前缀)
题目链接:用户登录 题目: 样例: 输入 5 3 aaa aba aabbaa abbbbb cdd aabba abc abab 输出 Y N N 思路: 根据题目意思,要用到 Trie 字典树算法。 Trie 字典树,顾名思义,“字典”࿰…...

全球移动通信(2G/3G/4G/5G)频谱分布情况
一、概述 随着通信技术的不断发展,全球各国都在积极推进2G、3G、4G、5G网络的建设和应用。根据FCC统计,目前全球移动通信频谱分布如下: 二、分布 (一)俄罗斯 2G:主要使用900MHz和1800MHz两个频段。其中&…...

【04】GeoScene导出海图或者电子航道图000数据成果
1创建一个带有覆盖面和定义的产品 如果你没有已存在的S-57数据,你可以通过捕捉新的产品覆盖范围(多边形产品范围)及其所需的产品定义信息(产品元数据)来为新产品创建基础。 注: 如果你已经有一个S-57数据…...

安卓端出现https请求失败(转)
背景# 某天早上,正在一个会议时,突然好几个同事被叫出去了;后面才知道,是有业务同事反馈到领导那里,我们app里面某个功能异常。 具体是这样,我们安卓版本的app是禁止截屏的(应该是app里做了拦…...

appium2.0.1安装完整教程+uiautomator2安装教程
第一步:根据官网命令安装appium(Install Appium - Appium Documentation) 注意npm前提是设置淘宝镜像: npm config set registry https://registry.npmmirror.com/ 会魔法的除外。。。 npm i --locationglobal appium或者 npm…...
Hbase的Rowkey设计
Hbase的Rowkey设计 rowkey设计 # 1)长度原则# 最大64KB,推荐长度10~100 byte# 最好设为8的倍数,能短则短,rowkey如果太长会影响性能。# 2)唯一原则:rowkey应该具备唯一性# 3)散列原则…...

软考机考考试第一批经验分享
由于机考的特殊性,考试环境与传统笔试环境有所不同。下面是与考试环境相关的总结: 草稿纸:考场提供足够数量的草稿纸,每位考生都会分发一张白纸作为草稿纸。在草稿纸上需要写上准考证号。如果不够用,可以向监考老师再次…...

架构简洁之道有感,谈谈软件组件聚合的张力
配图由腾讯混元助手生成 这篇文章介绍了软件架构设计中组件设计思想,围绕“组件间聚合的张力”这个有意思的角度,介绍了概念,并且结合架构设计示例对这个概念进行了进一步阐述。 组件聚合?张力?这标题,有种…...

计算机网络 网络层上 | IP数据报,IP地址,ICMP,ARP等
文章目录 1 网络层的两个层面2 网络协议IP2.1 虚拟互联网络2.2 IP地址2.2.1 固定分类编址方式2.2.2 无分类编制CIDR2.2.3 MAC地址和IP地址区别 2.3 地址解析协议ARP2.3.1 解析过程 2.4 IP数据报格式 3 IP层转发分组流程4 国际控制报文协议ICMP4.1 ICMP格式结构4.2 分类4.2.1 差…...

金智融门户(统一身份认证)同步数据至钉钉通讯录
前言:因全面使用金智融门户和数据资产平台,二十几个信息系统已实现统一身份认证和数据同步,目前单位使用的钉钉尚未同步组织机构和用户信息,职工入职、离职、调岗时都需要手工在钉钉后台操作,一是操作繁琐,二是钉钉通讯录更新不及时或经常遗漏,带来管理问题。通过金智融…...

eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)
说明: 想象一下,你正在用eNSP搭建一个虚拟的网络世界,里面有虚拟的路由器、交换机、电脑(PC)等等。这些设备都在你的电脑里面“运行”,它们之间可以互相通信,就像一个封闭的小王国。 但是&#…...

深入剖析AI大模型:大模型时代的 Prompt 工程全解析
今天聊的内容,我认为是AI开发里面非常重要的内容。它在AI开发里无处不在,当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗",或者让翻译模型 "将这段合同翻译成商务日语" 时,输入的这句话就是 Prompt。…...

微信小程序之bind和catch
这两个呢,都是绑定事件用的,具体使用有些小区别。 官方文档: 事件冒泡处理不同 bind:绑定的事件会向上冒泡,即触发当前组件的事件后,还会继续触发父组件的相同事件。例如,有一个子视图绑定了b…...
Java 语言特性(面试系列1)
一、面向对象编程 1. 封装(Encapsulation) 定义:将数据(属性)和操作数据的方法绑定在一起,通过访问控制符(private、protected、public)隐藏内部实现细节。示例: public …...
工业自动化时代的精准装配革新:迁移科技3D视觉系统如何重塑机器人定位装配
AI3D视觉的工业赋能者 迁移科技成立于2017年,作为行业领先的3D工业相机及视觉系统供应商,累计完成数亿元融资。其核心技术覆盖硬件设计、算法优化及软件集成,通过稳定、易用、高回报的AI3D视觉系统,为汽车、新能源、金属制造等行…...
关于 WASM:1. WASM 基础原理
一、WASM 简介 1.1 WebAssembly 是什么? WebAssembly(WASM) 是一种能在现代浏览器中高效运行的二进制指令格式,它不是传统的编程语言,而是一种 低级字节码格式,可由高级语言(如 C、C、Rust&am…...

JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作
一、上下文切换 即使单核CPU也可以进行多线程执行代码,CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短,所以CPU会不断地切换线程执行,从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...
汇编常见指令
汇编常见指令 一、数据传送指令 指令功能示例说明MOV数据传送MOV EAX, 10将立即数 10 送入 EAXMOV [EBX], EAX将 EAX 值存入 EBX 指向的内存LEA加载有效地址LEA EAX, [EBX4]将 EBX4 的地址存入 EAX(不访问内存)XCHG交换数据XCHG EAX, EBX交换 EAX 和 EB…...

2025季度云服务器排行榜
在全球云服务器市场,各厂商的排名和地位并非一成不变,而是由其独特的优势、战略布局和市场适应性共同决定的。以下是根据2025年市场趋势,对主要云服务器厂商在排行榜中占据重要位置的原因和优势进行深度分析: 一、全球“三巨头”…...
NPOI Excel用OLE对象的形式插入文件附件以及插入图片
static void Main(string[] args) {XlsWithObjData();Console.WriteLine("输出完成"); }static void XlsWithObjData() {// 创建工作簿和单元格,只有HSSFWorkbook,XSSFWorkbook不可以HSSFWorkbook workbook new HSSFWorkbook();HSSFSheet sheet (HSSFSheet)workboo…...