(十二)反射与特性-自定义特性(2)

news/2025/1/3 5:39:43/

一、自定义特性

特性是一种特殊的类。
要点:

  • 用户自定义的特性类叫作自定义特性。
  • 所有特性类都派生自 System.Attribute

1、声明自定义特性

声明:

public sealed class MyAttributeAttribute : System.Attribute
{
...
}

由于特性持有目标的信息,所有特性类的公有成员只能是:

  • 字段
  • 属性
  • 构造函数

2、使用特性的构造函数

构造函数的显式隐式声明定义,以及重载等等,规则跟其他类一样。

public MyAtrributeAttribute(string desc, string ver)
{
...
}

3、指定构造函数

[MyAttribute("Holds a value")]//使用一个字符串的构造函数
public int MyField;
[MyAttribute("Version 1.3", "Galen Daniel")]//使用两个字符串的构造函数
public void MyMethod()
{
...
}
//MyAttribute:特性类

特性构造函数要点:

  • 构造函数的实参必须是在编译时能确定值的常量表达式。
  • 如果构造函数没有参数,代码如下:
[MyAttr]
class SomeClass...
[MyAttr()]
class OtherClass...

4、使用构造函数

//命令语句
MyClass mc = new MyClass("Hello", 5);
//声明语句
[MyAttribute("Holds a value")]

特性类和其他类,比较构造函数的使用:

  • 命令语句的实际意义是:“在这里创建新的类。
  • 声明语句的意义是:“这个特性和这个目标相关联,如果需要构造特性,则使用这个构造函数。”

5、构造函数中的位置参数和命名参数

[MyAttribute("An excellent class", Reviewer="Amy McArthur",Ver="0.7.15.33")]
//位置参数:An excellent class
//命名参数:Reviewer="Amy McArthur"、Ver="0.7.15.33"

示例:

public sealed class MyAttributeAttribute : System.Attribute
{
public string Description;
public string Ver;
public string Reviewer;public MyAttributeAttribute(string desc)//一个形参
{
Description = desc;
}
}[MyAtrribute("An excellent class", Reviewer="Amy McArthur", Ver="7.15.33")]
class MyClass
{
...
}

二、限制特性的使用

AttributeUsage 特性: 用来限制将特性用在某个目标类型上。

如果希望自定义特性 MyAttribute 只能应用到方法上。

[AttributeUsage(AttributeTarget.Method)]
public sealed class MyAtrributeAttribute : System.Attribute
{
...
}

表-AttributeUsage 的公有属性

名字意义默认值
ValidOn保存能应用特性的目标类型的列表。构造函数的第一个参数必须是 AtrributeTargets 类型的枚举值
Inherited一个布尔值,它指示特性是否可被装饰类型的派生类所继承true
AllowMutiple一个布尔值,指示目标上是否可应用特性的多个实例的false

1、AtrributeUsage 的构造函数

AtrributeUsage 的构造函数接受单个位置参数,该参数指定了可使用特性的目标类型。它用这个参数来设置 ValidOn 属性,可接受的目标类型是 AttributeTargets 枚举的成员。

可用通过使用按位或运算符来组合使用类型。

[AttributeUsage(AttributeTarget.Method | AtrributeTarget.Constructor)]
public sealed class MyAttributeAttribute : System.Attribute
{
...
}

AttributeTargets 枚举的成员

AllAssemblyClassConstructor
DelegateEnumEventField
GenericParameterInterfaceMethodModule
ParameterPropertyReterunValueStruct
  • MyAttribute 只能应用到类上。
  • MyAttribute 不会被用用它的类的派生类所继承。
  • 不能在同一个目标上应用 MyAttribute 的多个实例。
[AttributeUsage(AttributeTarget.Class,Inherited = false,AllowMultiple = false)]
public sealed class MyAttribute : System.Attribute
{
...
}

三、自定义特性的最佳实践

1、自定义特性实践

建议自定义特性时:

  • 特性类应用表示目标结构的某种状态。
  • 如果特性需要某些字段,可以通过包含具有位置参数的构造函数来收集数据,可选字段可以用采用命名参数按需初始化。
  • 除了属性之外,不要实现公有方法或其他函数成员。
  • 为了更安全,把特性类声明为 sealed。
  • 在特性声明中使用 AttributeUsage 来显式指定特性目标组。
[AttributeUsage(AttributeTargets.Class)]
public sealed class ReviewCommentAtrribute : System.Attribute
{
public string Description {get; set;}
public string VersionNumber {get;set;}
public string ReviewrID {get;set;}public ReviewCommentAtrribute(string desc,string ver)
{
Description = desc;
VersionNumber = ver;
}
}

2、访问特性

使用 Type 对象来获取类型信息。Type 的两个方法:IsDefine 和 GetCustomAttributes。

1)使用 IsDefine 方法

可以使用 Type 对象 的 IsDefine 方法来检测某个特性是否应用到了某个类上。

[AttributeUsage(AttributeTargets.Class)]
public sealed class ReviewCommentAttribute : System.Attribute
{...}[ReviewComent("Check ite out","2.4")]
class MyClass{ }class Program
{
static void Main()
{
MyClass mc = new MyClass();
Type t = mc.GetType();
bool isDefined = t.IsDenfined(typeof(ReviewCommentAtrribute),false);if(isDefined)
{
Console.WriteLine($"ReviewComment is applied to type { t.Name }");
}
}
}

输出结果:

ReviewComment is applied tp type MyClass

2)使用 GetCustomAttributes 方法

Type 类的 GetCustomAttributes 方法返回用用到结构上的特性的数组。

  • 实际返回的对象时 object 数组,因此我们必须将它强制转换为相应的特性类型。
  • 布尔参数指定是否搜索继承树来查找特性。
object[] AttArr = t.GetCustomAttributes(false);
  • 调用 GetCustonnAttributes 方法后,每一个与目标相关联的特性的实例就会被创建。
    [AttributeUsage(AttributeTargets.Class)]public sealed class MyAtrributeAttribute : System.Attribute{public string Description { get; set; }public string VersionNumber { get; set; }public string ReviewerID { get; set; }public MyAtrributeAttribute(string desc, string ver){Description = desc;VersionNumber = ver;}}[MyAtrribute("Check it out","2.4")]class MyClass{ }class Program{static void Main(string[] args){Type t = typeof(MyClass);object[] AttArr = t.GetCustomAttributes(false);foreach(Attribute a in AttArr){MyAtrributeAttribute attr = a as MyAtrributeAttribute;if(null != attr){Console.WriteLine($"Decription   : { attr.Description }");Console.WriteLine($"Version Number   : { attr.VersionNumber }");Console.WriteLine($"Reviewer ID   : { attr.ReviewerID }");}}Console.ReadKey();}}

输出结果:

Decription : Check it out
Version Number : 2.4
Reviewer ID :


http://www.ppmy.cn/news/519383.html

相关文章

dvwa靶场通关(七)

第七关:SQL Injection(sql注入) low 我们输入 1,出现报错信息,根据报错信息可知,查询语句是单引号闭合的字符型 接着判断字段数 1 order by 3# 报错 1 order by 2# 正常 所以字段数就是2 利用联合查询爆出数据库名…

《医疗器械唯一标识系统规则》解读

一、什么是医疗器械唯一标识?   医疗器械唯一标识由产品标识和生产标识组成,产品标识是识别注册人/备案人、医疗器械型号规格和包装的唯一代码,是从数据库获取医疗器械相关信息的“关键字”,是唯一标识的必须部分;生…

医疗行业上云

目录 一、医疗云的发展环境二、趋势分析三、业务挑战四、行业大体痛点五、业务系统上云及合规框架(华为)六、AI药物研发框架(华为) 一、医疗云的发展环境 医疗信息化由三大模块构成:区域卫生信息化、医院信息化和基于…

2018年医疗人工智能技术与应用白皮书

前 言 2017 年医疗人工智能发展迅速,产业格局风起云涌。人工智能在医疗领域中的应用已非常广泛,包括医学影像、临床决策支持、语音识别、药物挖掘、健康管理、病理学等众多领域。人工智能技术呈现与医疗领域不断融合的趋势,其中数据资源、计…

springboot医疗管理系统毕业设计源码015221

目 录 摘要 1 绪论 1.1项目设计背景 1.2项目设计意义 1.3医疗管理系统设计目标 1.4系统开发技术的特色 4 1.5论文结构与章节安排 4 2 医疗管理系统分析 5 2.1 可行性分析 5 2.2 系统流程分析 6 2.2.1数据增加流程 7 2.3.2数据修改流程 7 2.3.3数据删除流程 8 2.3 系统功能…

NCU SEM 发文检索2014年

[1]冯宗品.基于SWOT法的民生银行投资价值分析[J].商,2014,09:292-293. [2]甘筱青,尤铭祥,胡凯.医保报销比例差距、患者行为选择与医疗费用的关系研究——基于三阶段动态博弈模型的分析[J].系统工程理论与实践,2014,11:2974-2983. 摘要:我国初步建立了覆盖全民的…

换帅半年,阿里健康扭亏为盈,医疗搜索成为互联网分级诊疗体系的发力点

关注ITValue,看企业级最新鲜、最价值报道!11月25日晚间,阿里健康信息技术有限公司(00241.HK,下称“阿里健康”)发布截止2020年9月30日止的2021财年中期业绩报告。 财报显示,阿里健康上半年营收达…

如何开发一套完整的医疗远程会诊系统方案

医疗远程会诊系统解决方案,利用物联网和远程通信等技术手段,实时将会诊室或手术室全景以及患者医疗数据或手术细节经由高速网络传输到会诊中心,由专家远程进行病情会诊以及手术指导,实现专家与病人、专家与医务人员之间异地“面对…