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. 766. Toeplitz Matrix - LeetCode

    Question 766. Toeplitz Matrix Solution 题目大意: 矩阵从每条左上到右下对角线上的数都相等就返回true否则返回false 思路: 遍历每一行[i,j]与[i+1 ...

  2. 一条更新SQL的内部执行及日志模块

    一条更新SQL的内部执行 学习MySQL实战45讲,非常推荐学 还是老图: 上文复习 在执行查询语句的时候,会执行连接器(总要连上才能搞事情),然后去查询缓存(MySQL8+删除了),有数据返回,没数 ...

  3. nacos 快速入门

    每日一句 外表可是具有欺骗性的. 每日一句 No victory comes without a price. 凡是成功就要付出代价. 概述 这个快速开始手册是帮忙您快速在您的电脑上,下载.安装并使用 ...

  4. LowDB采坑记录(主要为lowdb3.0的Cannot find module和lowdb1.0 node不断自启动的问题)

    bug1: Error [ERR_ MODULE_ NOT_ FOUND]: Cannot find module 在使用最新版LowDB(3.0)时,发现typescript中直接引用模块名(如以下 ...

  5. unittest自动化测试框架核心要素以及应用

    1. unittest核心要素 unittest介绍 测试框架,不仅仅用于单元测试 python自动的测试包 用法和django.test.TestCase类似 1.1.unitest介绍和核心要素 ...

  6. 1. Docker的中央仓库安装设置及镜像的操作

    具体也可参考:https://developer.aliyun.com/mirror/docker-ce?spm=a2c6h.13651102.0.0.3e221b11G7cfhr https://d ...

  7. C#/VB.NET 在Word转PDF时生成目录书签

    当我们在转换Word文档到PDF格式时,想保留Word文档的标题作为PDF书签,那么应该如何操作呢?那么本文将以C#及VB.NET代码为例,介绍如何在Word转PDF时生成目录书签.下面是具体方法和步 ...

  8. React项目中使用less/scss&全局样式/变量

    使用create-react-app脚手架搭建初始化项目 > npm install -g create-react-app > npx create-react-app my-app c ...

  9. .NetCore实现图片缩放与裁剪 - 基于ImageSharp

    前言 (突然发现断更有段时间了 最近在做博客的时候,需要实现一个类似Lorempixel.LoremPicsum这样的随机图片功能,图片有了,还需要一个根据输入的宽度高度获取图片的功能,由于之前处理图 ...

  10. Windows下MySQL的安装和删除

    Windows下MySQL的安装和删除 安装Mysql 1 下载mysql 地址 2 安装教程 2.1配置环境变量 变量名:MYSQL_HOME 变量值:D:\software\programming ...