C基础 - 特性

一.特性

1>特性本质就是一个,直接或者间接的继承了Attribute

2>特性就是在不破话类封装的前提下,加点额外的信息或者行为

特性添加后,编译会在元素内部产生IL,我们没办法直接使用,在metadata中是有的

二.应用场景之-枚举上加描述

运行结果如下图

 1 using System;
2 using System.Reflection;
3
4 namespace ConsoleApp1
5 {
6 public enum RunState
7 {
8 [RemarkEnum(Remark = "正在运行")]
9 Running = 0,
10
11 [RemarkEnum(Remark = "停止")]
12 Stop = 1,
13
14 [RemarkEnum(Remark = "完成")]
15 Finish = 2,
16 }
17 class Program
18 {
19 static void Main(string[] args)
20 {
21 Console.WriteLine(RunState.Running.GetRemark());
22 Console.WriteLine(RunState.Stop.GetRemark());
23 Console.WriteLine(RunState.Finish.GetRemark());
24 Console.ReadKey();
25 }
26 }
27 public class RemarkEnumAttribute : Attribute
28 {
29 public string Remark { get; set; }
30 }
31 /// <summary>
32 /// 扩展方法:静态类,静态方法,this这三个部分造成
33 /// 调用的时候,直接对象.方法名
34 /// </summary>
35 public static class RemarkExtend
36 {
37 public static string GetRemark(this Enum enumValue)
38 {
39 Type type = enumValue.GetType();
40 FieldInfo field = type.GetField(enumValue.ToString());
41 if (field.IsDefined(typeof(RemarkEnumAttribute), true))//访问特性的标准流程
42 {
43 RemarkEnumAttribute attribute = (RemarkEnumAttribute)field.GetCustomAttribute(typeof(RemarkEnumAttribute), true);
44 return attribute.Remark;
45 }
46 else
47 {
48 return enumValue.ToString();
49 }
50 }
51 }
52 }

三.应用场景值之-结构体加描述

运行结果如下图

 1 using System;
2 using System.Reflection;
3
4 namespace ConsoleApp1
5 {
6 public struct CommPara
7 {
8 [StructExten(Remark = "串口号")]
9 public string CommPort;
10 [StructExten(Remark = "Id号")]
11 public int Id;
12 }
13 class Program
14 {
15 static void Main(string[] args)
16 {
17 CommPara comm = new CommPara()
18 {
19 CommPort = "Com1",
20 Id = 10,
21 };
22 Console.WriteLine(comm.GetRemark());
23 Console.ReadKey();
24 }
25 }
26
27 [AttributeUsage(AttributeTargets.Struct | AttributeTargets.Field)]
28 public class StructExtenAttribute : Attribute
29 {
30 public string Remark { get; set; }
31 }
32 public static class RemarkStructExtend
33 {
34 public static string GetRemark(this object enumValue)
35 {
36 string Name = string.Empty;
37 Type type = enumValue.GetType();
38 FieldInfo[] fields = type.GetFields();
39 foreach (var field in fields)
40 {
41 if (field.IsDefined(typeof(StructExtenAttribute), true))
42 {
43 StructExtenAttribute attribute = (StructExtenAttribute)field.GetCustomAttribute(typeof(StructExtenAttribute), true);
44 Name += $"{ attribute.Remark},";
45 }
46 else
47 {
48 Name = enumValue.ToString();
49 }
50 }
51 return Name;
52 }
53 }
54 }

四.访问类,属性,方法上的特性,另外特性上加一些验证行为

调用实例如下:

首先控制台项目中,添加Student类,Manager类,Validate特性类,这些类见下面,添加好后如下图显示的:

 1 using System;
2
3 namespace _002_Attribute
4 {
5 class Program
6 {
7 static void Main(string[] args)
8 {
9 try
10 {
11 Student student = new Student()
12 {
13 Name = "小王",
14 Id = 100,
15 QQ = 10002,
16 };
17 Manager.Show<Student>(student);
18 Console.ReadKey();
19 }
20 catch (Exception ex)
21 {
22
23 }
24 }
25 }
26 }

运行结果如下图

Student类

 1 using System;
2
3 namespace _002_Attribute
4 {
5 [Remark(Description = "学生")]
6 public class Student
7 {
8 [Length(1, 5)]
9 [Remark(Description = "我是Name")]
10 public string Name { get; set; }
11
12 [Remark(Description = "学生的Id")]
13 public int Id { get; set; }
14
15
16 [Long(10001, 999999)]
17 public int QQ { get; set; }
18
19 [Remark(Description = "我在学习")]
20 public void Study([Remark]string name)
21 {
22 Console.WriteLine($"{name} study now!");
23 }
24 }
25 }

Manager类:只要是程序运行的时候,使用特性

 1 using System;
2 using System.Reflection;
3
4 namespace _002_Attribute
5 {
6 public class Manager
7 {
8 public static void Show<T>(T student)
9 {
10 Type type = typeof(T);
11 //访问类的特性
12 if (type.IsDefined(typeof(RemarkAttribute), true))//类访问特性
13 {
14 RemarkAttribute reamrk = (RemarkAttribute)type.GetCustomAttribute(typeof(RemarkAttribute), true);
15 Console.WriteLine($"我是类上的特性:{reamrk.Description}");
16 reamrk.Show();
17 }
18
19 Console.WriteLine("******************************************************************");
20 //访问Id属性的特性
21 PropertyInfo property = type.GetProperty("Id");
22 if (property.IsDefined(typeof(RemarkAttribute), true))
23 {
24 RemarkAttribute remark = (RemarkAttribute)property.GetCustomAttribute(typeof(RemarkAttribute), true);
25 Console.WriteLine($"我是属性的特性:{remark.Description}");
26 remark.Show();
27 }
28 Console.WriteLine("******************************************************************");
29 //访问所有属性的特性
30 PropertyInfo[] propertys = type.GetProperties();
31 foreach (var prop in propertys)
32 {
33 if (prop.IsDefined(typeof(RemarkAttribute), true))
34 {
35 RemarkAttribute remark = (RemarkAttribute)prop.GetCustomAttribute(typeof(RemarkAttribute), true);
36 Console.WriteLine($"我是属性的特性:{remark.Description}");
37 }
38 }
39
40 Console.WriteLine("******************************************************************");
41 //访问方法的特性
42 MethodInfo method = type.GetMethod("Study");
43 if (method.IsDefined(typeof(RemarkAttribute), true))
44 {
45 RemarkAttribute remark = (RemarkAttribute)method.GetCustomAttribute(typeof(RemarkAttribute), true);
46 Console.WriteLine($"我说方法的特性:{remark.Description}");
47 remark.Show();
48 }
49
50 Console.WriteLine("******************************************************************");
51 //访问方法参数的特性
52 ParameterInfo parameter = method.GetParameters()[0];
53 if (parameter.IsDefined(typeof(RemarkAttribute), true))
54 {
55 RemarkAttribute remark = (RemarkAttribute)parameter.GetCustomAttribute(typeof(RemarkAttribute), true);
56 Console.WriteLine($"我是方法参数上的特性:{remark.Description}");
57 remark.Show();
58 }
59
60 //特性上加一些验证的行为
61 student.Validate();
62
63 }
64 }
65 }

Validate特性类,自定义的特性

 1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.Threading.Tasks;
6
7 namespace _002_Attribute
8 {
9 /// <summary>
10 /// 扩展方法:静态类,静态字段,this这单个特征组成的
11 /// </summary>
12 public static class ValidateExtension
13 {
14 public static bool Validate(this object oObject)
15 {
16 Type type = oObject.GetType();
17 foreach (var prop in type.GetProperties())
18 {
19 if (prop.IsDefined(typeof(AbstractValidateBase), true))
20 {
21 object[] attributeArray = prop.GetCustomAttributes(typeof(AbstractValidateBase), true);//得到所有的特性
22 foreach (AbstractValidateBase attribute in attributeArray)
23 {
24 if (!attribute.Validate(prop.GetValue(oObject)))
25 {
26 return false;
27 }
28 }
29 }
30 }
31 return true;
32 }
33 }
34 /// <summary>
35 /// 抽象的基类
36 /// </summary>
37 public abstract class AbstractValidateBase : Attribute
38 {
39 public abstract bool Validate<T>(T tValue);
40 }
41 [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
42 public class LengthAttribute : AbstractValidateBase
43 {
44 private int _Min = 0;
45 private int _Max = 0;
46 public LengthAttribute(int min, int max)
47 {
48 this._Min = min;
49 this._Max = max;
50 }
51 public override bool Validate<T>(T tValue)
52 {
53 int length = tValue.ToString().Length;
54 if (length > this._Min && length < this._Max)
55 {
56 return true;
57 }
58 return false;
59 }
60 }
61 [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
62 public class LongAttribute : AbstractValidateBase
63 {
64 private long _Min = 0;
65 private long _Max = 0;
66 public LongAttribute(long min, long max)
67 {
68 this._Min = min;
69 this._Max = max;
70 }
71 public override bool Validate<T>(T tValue)
72 {
73 if (tValue != null && !string.IsNullOrWhiteSpace(tValue.ToString()))
74 {
75 if (long.TryParse(tValue.ToString(), out long result))//新语法,out这里不用提前声明变量了,直接写就行了
76 {
77 if (result > this._Min && result < this._Max)
78 {
79 return true;
80 }
81 }
82 }
83 return true;
84 }
85 }
86 public class RemarkAttribute : Attribute
87 {
88 public RemarkAttribute()
89 {
90
91 }
92 public string Description { get; set; }
93 public void Show()
94 {
95 Console.WriteLine($"This is {nameof(RemarkAttribute)}");
96 }
97 }
98 }

C# 基础知识-特性的更多相关文章

  1. C#基础知识之面向对象以及面向对象的三大特性

    在C#基础知识之类和结构体中我详细记录了类.类成员.重载.重写.继承等知识总结.这里就记录一下对面向对象和面向对象三大特性的广义理解. 一.理解面向对象 类是面向对象编程的基本单元,面向对象思想其实就 ...

  2. RabbitMQ基础知识

    RabbitMQ基础知识 一.背景 RabbitMQ是一个由erlang开发的AMQP(Advanced Message Queue )的开源实现.AMQP 的出现其实也是应了广大人民群众的需求,虽然 ...

  3. [SQL] SQL 基础知识梳理(四) - 数据更新

    SQL 基础知识梳理(四) - 数据更新 [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/5929786.html 序 这是<SQL 基础知识梳理( ...

  4. 前端开发:css基础知识之盒模型以及浮动布局。

    前端开发:css基础知识之盒模型以及浮动布局 前言 楼主的蛮多朋友最近都在学习html5,他们都会问到同一个问题 浮动是什么东西?  为什么这个浮动没有效果?  这个问题楼主已经回答了n遍.今天则是把 ...

  5. TCP/IP协议(二)tcp/ip基础知识

    今天凌晨时候看书,突然想到一个问题:怎样做到持续学习?然后得出这样一个结论:放弃不必要的社交,控制欲望,克服懒惰... 然后又有了新的问题:学习效率时高时低,状态不好怎么解决?这也是我最近在思考的问题 ...

  6. TCP/IP协议(一)网络基础知识

    参考书籍为<图解tcp/ip>-第五版.这篇随笔,主要内容还是TCP/IP所必备的基础知识,包括计算机与网络发展的历史及标准化过程(简述).OSI参考模型.网络概念的本质.网络构建的设备等 ...

  7. Linux基础知识整理

    一.基础知识 1.Linux简介 Linux是一套免费使用和自由传播的类Unix操作系统,是一个基于POSIX和UNIX的多用户.多任务.支持多线程和多CPU的操作系统.它能运行主要的UNIX工具软件 ...

  8. 基础知识漫谈(2):从设计UI框架开始

    说UI能延展出一丢丢的东西来,光java就有swing,swt/jface乃至javafx等等UI toolkit,在桌面上它们甚至都不是主流,在web端又有canvas.svg等等. 基于这些UI工 ...

  9. Python黑帽编程3.0 第三章 网络接口层攻击基础知识

    3.0 第三章 网络接口层攻击基础知识 首先还是要提醒各位同学,在学习本章之前,请认真的学习TCP/IP体系结构的相关知识,本系列教程在这方面只会浅尝辄止. 本节简单概述下OSI七层模型和TCP/IP ...

随机推荐

  1. Flutter 状态管理框架 Provider 和 Get 分析

    文/ Nayuta,CFUG 社区 状态管理一直是 Flutter 开发中一个火热的话题.谈到状态管理框架,社区也有诸如有以 Get.Provider 为代表的多种方案,它们有各自的优缺点. 面对这么 ...

  2. 弃用!Github 上用了 Git.io 缩址服务的都注意了

    GitHub 是面向开源及私有软件项目的托管平台,因为只支持 Git 作为唯一的版本库格式进行托管,故名 GitHub.对程序员来说,GitHub 可以说是开源精神之所系.在 GitHub 任何职业程 ...

  3. ubuntu 获取 gateway 网关 ip

    输入以下命令,第一行中 Gateway 列就是网关 IP netstat -rn

  4. 2. springboot加载配置参数顺序

    加载顺序依次是:1.jar的classes里面的application.properties 2.当前路径下config里面的application.properties 3.jar的classes里 ...

  5. JNPF移动办公解决方案

    市场背景 随着办公自动化系统的普及,电子化.数据化的办公方式已进入越来越多的企业和政府单位,信息化的办公系统在企事业内部编织起一套高效.畅通的信息互联体系,极大推动了企事业单位生产力的发展.但与此同时 ...

  6. vue根据后端菜单自动生成路由(动态路由)

    vue根据后端菜单自动生成路由(动态路由) router.js import Vue from 'vue' import Router from 'vue-router' import store f ...

  7. MAUI模板项目闪退问题

    MAUI模板项目闪退问题 在MAUI最初发布的时候就曾创建过几个模板项目进行体验过,没遇到什么坑.由于最近需要开发针对餐饮行业的收银机(安卓系统)开发一款应用,这种收银机一般配置不咋滴,系统版本和性能 ...

  8. springboot2.7.x 集成log4j2配置写入日志到mysql自定义表格

    在阅读之前请先查看[springboot集成log4j2] 本文暂不考虑抽象等实现方式,只限于展示如何自定义配置log4j2并写入mysql数据库(自定义结构) 先看下log4j2的配置 <?x ...

  9. orcal恢复delete误删除的数据

    orcal的删除有3种:delete.truncate.drop. delete可以手动提交和回滚,且可以使用where:而truncate.drop执行即对表数据进行了修改,且不能使用where. ...

  10. go-zero微服务实战系列(七、请求量这么高该如何优化)

    前两篇文章我们介绍了缓存使用的各种最佳实践,首先介绍了缓存使用的基本姿势,分别是如何利用go-zero自动生成的缓存和逻辑代码中缓存代码如何写,接着讲解了在面对缓存的穿透.击穿.雪崩等常见问题时的解决 ...