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. DOM操作标签、事件绑定、jQuery框架/类库

    DOM操作标签 ''' 在起变量名的时候 如果该变量指向的是一个标签 那么建议使用 xxxEle eg:aEle\pEle\divEle\spanEle ''' # 动态创建一个a标签并添加到页面指定 ...

  2. django-rest-framework 基础三 认证、权限和频率

    django-rest-framework 基础三 认证.权限和频率 目录 django-rest-framework 基础三 认证.权限和频率 1. 认证 1.1 登录接口 1.2 认证 2. 权限 ...

  3. 石油储运生产 2D 可视化,组态应用赋能工业智慧发展

    前言 当前,国际油价低位徘徊导致各国石油化工行业投资大幅缩减,石油化工建设行业竞争环境日趋严峻,施工企业的利润空间也被不断压缩.内外交困的环境下,促使企业采取更有效的管理手段来提高效率和降低成本.石油 ...

  4. 理解 Object.defineProperty

    理解 Object.defineProperty 本文写于 2020 年 10 月 13 日 Object.defineProperty 用于在一个对象上定义新的属性或修改现有属性并返回该对象. 什么 ...

  5. 使用VPLS跨地域多站点建立二层交换网络

    VLL解决方案 https://www.cnblogs.com/darkchen/p/14652540.html 接上篇文档引出VPLS VLL可以跨地域建立二层交换网络,但有个缺陷是只支持两个sit ...

  6. awk内建函数

    内建函数 length() 获得字符串长度 cat score.txt Marry 2143 78 84 77 Jack 2321 66 78 45 Tom 2122 48 77 71 Mike 25 ...

  7. 分享一个 SpringCloud Feign 中所埋藏的坑

    背景 前段时间同事碰到一个问题,需要在 SpringCloud 的 Feign 调用中使用自定义的 URL:通常情况下是没有这个需求的:毕竟都用了 SpringCloud 的了,那服务之间的调用都是走 ...

  8. .NET MAUI 正式发布,再见了 Xamarin.Forms

    David Ortinau 在dotnet 团队博客上发表了一篇文章<Introducing .NET MAUI – One Codebase, Many Platforms>,在这篇文章 ...

  9. 关于我学git这档子事(4)

    ------------恢复内容开始------------ 当本地分支(main/dev)比远程仓库分支(main/dev)落后几次提交时 先: git pull 更新本地仓库 再 git push ...

  10. [BZOJ5449] 序列

    题目链接:序列 Description 给定一个\(1\)~\(n\)的排列x,每次你可以将 \(x_1, x_2, ..., x_i\) 翻转. 你需要求出将序列变为升序的最小操作次数. 多组数据. ...