目录

一、前期准备

二、特性概念

三、特性案例

1、基础特性 -- 自定义

2、特性实战 -- 自定义

3、常用特性类 -- 官方

1、ObsoleteAttribute

2、AttributeUsageAttribute

3、ConditionalAttribute

4、CallerFilePath、CallerLineNumber、CallerMemberName

5、DebuggerStopThrough

6、RequiredAttribute


涉及知识点:   特性    反射

一、前期准备

 引入using:

using System;
using System.ComponentModel.DataAnnotations;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;

二、特性概念

特性: 他就是一个类, 继承Attribute,在特性类中,一般只配置 字段、属性、构造方法
使用场景:数据验证
特性三大步:
         第一步 -- 定义特性  (编写一个类)
                               类需要继承Attribute,
                               并以Attribute为后缀
         第二步 -- 标记 -- 标记时可省略Attribute后缀
         第三步 -- 反射调用

三、特性案例

1、基础特性 -- 自定义

代码编写:

    class NameAttribute : Attribute  //第一步创建以Attribute结尾的类,并继承Attribute类{public string name; //字段public int Id { set; get; } //属性public NameAttribute(string name) //构造方法{this.name = name;}public NameAttribute(string name, int id) //构造方法{this.name = name;this.Id = id;}}class Student{[Name("小王", 1)] //第二步 标记特性,可省略Attribute后缀public int Id { get; set; }[Name("小白")]public string Name { get; set; }}class AttributeInvoke{public static void Invoke<T>(T t) //第三步编写反射调用特性使用方法{//获取类Type type = typeof(T);//遍历类中的属性foreach (PropertyInfo property in type.GetProperties()){//若该属性有NameAttribute标记if (property.IsDefined(typeof(NameAttribute), true)){ //获取NameAttribute特性NameAttribute name = property.GetCustomAttribute<NameAttribute>();Console.WriteLine(name.name);Console.WriteLine(name.Id);}}}}internal class Program{static void Main(string[] args){Student student = new Student();AttributeInvoke.Invoke(student);Console.WriteLine("Hello World!");}}

结果显示:

2、特性实战 -- 自定义

第一步:创建抽象公共特性类
第二步:编写多个正常特性类,继承公共特性类
第三步:编写反射调用特性方法
第四步:标记,并调用特性方法,校验

代码编写:

    //第一步: 创建抽象公共特性类public abstract class CommonValidateAttribute : Attribute{public abstract bool Validate(object obj);}//第二步: 编写多个正常特性类,继承公共特性类[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]public class LengthAttribute : CommonValidateAttribute{public int Max;public int Min;public LengthAttribute(int max, int min){Max = max;Min = min;}public override bool Validate(object objValue){return objValue != null &&objValue.ToString().Length < Max &&objValue.ToString().Length > Min;}}public class NameLengthAttribute : CommonValidateAttribute{public int count;public NameLengthAttribute(int count){this.count = count;}public override bool Validate(object objValue){return objValue.ToString().Length == count;}}//第三步:编写反射调用特性方法public class AttributeInvoke{public static bool Invoke<T>(T t){Type type = typeof(T);foreach (FieldInfo field in type.GetFields()){Object objValue = field.GetValue(t);foreach (CommonValidateAttribute item in field.GetCustomAttributes(typeof(CommonValidateAttribute), true)){return item.Validate(objValue);}}return false;}}//第四步:标记,并调用特性方法,校验public class Student{[NameLength(3)]public string name;[Length(15, 8)]public long Phone;}internal class Program{static void Main(string[] args){string information;Student Tom = new Student(){name = "王小红",Phone = 123456789};information = AttributeInvoke.Invoke(Tom) ?  "数据正确" : "数据格式错误";Console.WriteLine(information);Student Jack = new Student(){name = "小白",Phone = 123};information = AttributeInvoke.Invoke(Jack) ? "数据正确" : "数据格式错误";Console.WriteLine(information);}}

结果显示:

3、常用特性类 -- 官方

1、ObsoleteAttribute

概念:

       [Obsolete] -- 类已过时
                       -- 系统自动调用
                       -- 默认警告提示

代码编写:

    internal class Program{static void Main(string[] args){Student Tom = new Student(){id = 2,       //绿色波浪线name = "Tom", //绿色波浪线phone = 15258545856, //红色波浪线email = "2578395032@qq.com", //绿色波浪线};Console.WriteLine("Hello World!");}}public class Student{[Obsolete]  // 已过时(抛警告)public int id;[Obsolete("2022.12.10废弃")] //默认是false -- 推荐public string name;[Obsolete("不可用", true)]  //调用时报红色波浪线错误 -- 编译不可以通过,错误public long phone;[Obsolete("已废弃", false)] //调用时报绿色波浪线警告 -- 编译可以通过,警告public string email;}

结果显示:

2、AttributeUsageAttribute

概念:

[AttributeUsage] -- 配置特性标记范围

代码编写:

    //设置Student特性只能应用于类和方法上,默认 不允许多个特性,可查询特性的父类[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]public class TeacherAttribute : Attribute{public TeacherAttribute() { }}[Teacher][Teacher]  //报红,报错,不可标记多个特性public class Student{[Teacher]  //报红,报错,只能标记在类和方法上面public string Name { get; set; }}

3、ConditionalAttribute

概念:

[Conditional]   -- 条件编译 -- 只可应用在方法和特性类上
                             -- 若定义,正常调用
                             -- 若未定义,则不被调用

代码编写:

    #define teacherAttribute//#define fun[Conditional("teacherAttribute")]public class TeacherAttribute : Attribute{public string name;public TeacherAttribute(string name){this.name = name;}}[Teacher("学生")]public class Student{[Conditional("teacherAttribute")]public void Music() => Console.WriteLine("听音乐");[Conditional("fun")]public void Song() => Console.WriteLine("唱歌");}internal class Program{static void Main(string[] args){Student student = new Student();student.Music(); //fun 定义 -- 运行student.Song(); //teacherAttribute 未定义 -- 不运行//校验Teacher特性 -- fun 定义,运行Type type = typeof(Student);if (type.IsDefined(typeof(TeacherAttribute), true)){TeacherAttribute attribute = (TeacherAttribute)type.GetCustomAttribute(typeof(TeacherAttribute), true);Console.WriteLine(attribute.name);}Console.WriteLine("Hello World!");}}

结果显示:

4、CallerFilePath、CallerLineNumber、CallerMemberName

概念:

        只可用于方法的入参
        [CallerFilePath] --文件路径
        [CallerLineNumber] -- 代码行数
        [CallerMemberName] -- 成员名称

代码编写:

    //只可应用于参数internal class Program{static void Main(string[] args){Student student = new Student();student.Music();Console.WriteLine("Hello World!");}}class Student{public void Music([CallerMemberName] string memberName = "",[CallerFilePath] string filePath = "",[CallerLineNumber] int lineNumber = 0){Console.WriteLine("听音乐");Console.WriteLine("memberName: " + memberName);Console.WriteLine("filePath:   " + filePath);Console.WriteLine("lineNumber  " + lineNumber);}}

结果显示:

5、DebuggerStopThrough

概念:

[DebuggerStopThrough] -- 调试时不进入此方法,方法内部正常调用

代码编写:

    internal class Program{static void Main(string[] args){Student student = new Student();student.Music();Console.WriteLine("Hello World!");}}class Student{[DebuggerStepThrough] //调试时不进入此方法,方法内部正常调用public void Music(){Console.WriteLine("听音乐");}}

6、RequiredAttribute

概念:

[Required] -- 属性不能为 ""
                        -- 一般应用于string类型上面,不建议放在int类型上面

代码编写:

    internal class Program{static void Main(string[] args){Student student = new Student();Type type = typeof(Student);foreach (PropertyInfo property in type.GetProperties()){object objValue = property.GetValue(student);if (property.IsDefined(typeof(RequiredAttribute), true)){RequiredAttribute required = (RequiredAttribute)property.GetCustomAttribute(typeof(RequiredAttribute), true);if (!required.IsValid(objValue)){Console.WriteLine($"{property.Name} 验证不通过");}}}Console.WriteLine("--" +student.Name);Console.WriteLine("--" +student.Id);Console.WriteLine("Hello World!");}}class Student{[Required] //int一般不用这个特性public int Id { get; set; }[Required] //一般应用于string类型public string Name { get; set; }}

结果显示:

如有错误,烦请批评指正

Attribute特性定义及应用相关推荐

  1. [C#]Attribute特性(2)——方法的特性及特性参数

    上篇博文[C#]Attribute特性介绍了特性的定义,类的特性,字段的特性,这篇博文将介绍方法的特性及特性参数相关概念. 3.方法的特性 之所以将这部分单列出来进行讨论,是因为对方法的特性查询的反射 ...

  2. Attribute特性3——自定义特性AttributeUsage

    Attribute特性3--自定义特性AttributeUsage AttributeUsage 预定义特性 AttributeUsage 描述了如何使用一个自定义特性类.它规定了特性可应用到的项目的 ...

  3. C#基础系列——Attribute特性使用

    前言:上篇 C#基础系列--反射笔记 总结了下反射得基础用法,这章我们来看看C#的另一个基础技术--特性. 1.什么是特性:就博主的理解,特性就是在类的类名称.属性.方法等上面加一个标记,使这些类.属 ...

  4. “.NET研究”关于C# 中的Attribute 特性

    Attribute与Proper上海企业网站制作ty 的翻译区别 Attribute 一般译作"特性",Property 仍然译为"属性". Attribute ...

  5. .Net Attribute特性

    1.特性Attribute不能和属性Property混为一谈, 这是完全不同的两个东西. 2.特性Attribute给类或方法标识的内容, 可以在程序运行的时侯, 通过反射获取到. 例如1: .net ...

  6. IOC容器特性注入第五篇:查找(Attribute)特性注入

    前面几篇文章分别介绍:程序集反射查找,特性,容器,但它们之间贯穿起来,形成查找Attribute注入IOC容器,就得需要下面这个类帮忙: 1.DependencyAttributeRegistrato ...

  7. Attribute 特性详解

    详解 概述 特性的一些使用 重复特性 使用带构造函数或者参数的 标记过期的 使用特性 位置 概述 特性是一个直接或间接继承自Attribute的类 特性编译后是metadata 只有反射才能使用 特性 ...

  8. 利用Attribute特性简化多查询条件拼接sql语句的麻烦

    最近公司在做武汉公交信息化管理系统,做这种管理项目,最让人痛苦的就是表单的添加.修改.查询.添加.修改在我以前的文章中提到过,利用反射机制可以做到基本不写代码来完成.参见<ORM框架实现数据的自 ...

  9. 移动简报026—智慧餐厅出新服务:吃饭用微信就可排队;支付宝上线银行卡安全险:盗刷最高获赔 50 万;高德正式发布车载导航App...

    移动简报026 [移动营销] 艾瑞:2015年中国移动广告市场规模突破900亿 2015年移动广告市场规模达到901.3亿元,同比增长率高达178.3%,发展势头十分强劲.移动广告的整体市场增速远远高 ...

最新文章

  1. 有没有想过,自己手写一个连接池?
  2. 块级元素内联并列显示
  3. 责任链模式——HeadFirst设计模式学习笔记
  4. 从零开始实现ASP.NET Core MVC的插件式开发(六) - 如何加载插件引用
  5. 俄语使用计算机怎么说,计算机俄语常用词汇
  6. 我自横刀向天笑,我命由我不由天
  7. java 课后习题 月历打印
  8. pytest+allure之测试报告本地运行
  9. python groupby用法_Python 标准库实践之合并字典组成的列表
  10. Q98:三角形网格细分Bezier曲面时,注意三角形顶点的顺序(确保其对应的法向量向外)
  11. HTML Button.onclick事件汇总
  12. rabbitmq多个消费者_选型必看:RabbitMQ 七夕 Kafka,差异立现
  13. js高级学习笔记(b站尚硅谷)-16-原型链的继承
  14. mac配置adb环境变量
  15. Freecad的Python脚本
  16. 高薪物联网职业生涯所需的十大技能(转)
  17. pg客户端连接报错:不支援 10 验证类型。请核对您已经组态  ..
  18. 网络营销之网络炒作案例分析、精髓及方法讨论
  19. php按钮如何加显示不出来,javascript - 点击按钮 显示更多,自定义变量显示不出来?...
  20. Word-embeding 【paper】

热门文章

  1. java 定义一个学生类,利用无参和带参方法调用
  2. 收不到手机验证码怎么办
  3. 基于uniapp开发app,省市区联动
  4. 【和UI斗智斗勇的日子】如何实现一个类似哈罗单车APP主页打车模块的卡片式切的View
  5. excel 修改设置(将excel修改后缀名,解压缩方式)
  6. dilated conv的理解
  7. 华芯微特SWM320TFT屏人机交互方案手册
  8. WinForm中新开一个线程操作窗体上的控件(跨线程操作控件)GOOD
  9. 8个亿!河南首富再次无偿捐款西湖大学,西湖大学河南籍校董高达11位
  10. 计算机英语构词法,【计算机专业论文】计算机专业英语的构词方法(共2969字)