C# 基础知识-特性
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# 基础知识-特性的更多相关文章
- C#基础知识之面向对象以及面向对象的三大特性
在C#基础知识之类和结构体中我详细记录了类.类成员.重载.重写.继承等知识总结.这里就记录一下对面向对象和面向对象三大特性的广义理解. 一.理解面向对象 类是面向对象编程的基本单元,面向对象思想其实就 ...
- RabbitMQ基础知识
RabbitMQ基础知识 一.背景 RabbitMQ是一个由erlang开发的AMQP(Advanced Message Queue )的开源实现.AMQP 的出现其实也是应了广大人民群众的需求,虽然 ...
- [SQL] SQL 基础知识梳理(四) - 数据更新
SQL 基础知识梳理(四) - 数据更新 [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/5929786.html 序 这是<SQL 基础知识梳理( ...
- 前端开发:css基础知识之盒模型以及浮动布局。
前端开发:css基础知识之盒模型以及浮动布局 前言 楼主的蛮多朋友最近都在学习html5,他们都会问到同一个问题 浮动是什么东西? 为什么这个浮动没有效果? 这个问题楼主已经回答了n遍.今天则是把 ...
- TCP/IP协议(二)tcp/ip基础知识
今天凌晨时候看书,突然想到一个问题:怎样做到持续学习?然后得出这样一个结论:放弃不必要的社交,控制欲望,克服懒惰... 然后又有了新的问题:学习效率时高时低,状态不好怎么解决?这也是我最近在思考的问题 ...
- TCP/IP协议(一)网络基础知识
参考书籍为<图解tcp/ip>-第五版.这篇随笔,主要内容还是TCP/IP所必备的基础知识,包括计算机与网络发展的历史及标准化过程(简述).OSI参考模型.网络概念的本质.网络构建的设备等 ...
- Linux基础知识整理
一.基础知识 1.Linux简介 Linux是一套免费使用和自由传播的类Unix操作系统,是一个基于POSIX和UNIX的多用户.多任务.支持多线程和多CPU的操作系统.它能运行主要的UNIX工具软件 ...
- 基础知识漫谈(2):从设计UI框架开始
说UI能延展出一丢丢的东西来,光java就有swing,swt/jface乃至javafx等等UI toolkit,在桌面上它们甚至都不是主流,在web端又有canvas.svg等等. 基于这些UI工 ...
- Python黑帽编程3.0 第三章 网络接口层攻击基础知识
3.0 第三章 网络接口层攻击基础知识 首先还是要提醒各位同学,在学习本章之前,请认真的学习TCP/IP体系结构的相关知识,本系列教程在这方面只会浅尝辄止. 本节简单概述下OSI七层模型和TCP/IP ...
随机推荐
- 【翻译】ScyllaDB数据建模的最佳实践
文章翻译自Scylla官方文档:https://www.scylladb.com/2019/08/20/best-practices-for-data-modeling/ 转载请注明出处:https: ...
- a commponent required a bean of type XXXXXX that could not be found-2022新项目
一.问题由来 目前刚入职一家新公司不久,公司的新项目采用DDD驱动领域设计来进行开发,架构这一块使用的是阿里巴巴开源的最新框架COLA4.0的架构. 主要是这个框架里面的分层设计.主要分为四层:ada ...
- c++动态内存分配需要注意的地方,可以不用尽量不用
在实际开发中,需要动态分配内存的场景极少,string和vector已经足够方便,如果不是非用不可的情况,采用动态分配内存就是给自己挖坑. 如果应用开发中一定要用动态内存分配技术,建议把它封装在类中, ...
- data:image字符转byte[]
var data = "data:image/bmp;base64,Qk3aHwAAAAAAADYAAAAoAAAAZAAAABsAAAABABgAAAAAAKQfAAAAAQAAAAEAA ...
- 好客租房16-jsx中的列表渲染
如果要渲染一组数组 应该使用数组的map方法 注意:渲染列表时候添加key属性 key属性的值要保持唯一 原则:map()遍历谁 就给谁添加key属性 尽量避免索引号作为key //导入react i ...
- 面试官:Netty心跳检测机制是什么,怎么自定义检测间隔时间?
哈喽!大家好,我是小奇,一位热爱分享的程序员 小奇打算以轻松幽默的对话方式来分享一些技术,如果你觉得通过小奇的文章学到了东西,那就给小奇一个赞吧 文章持续更新 一.前言 书接上回,昨天在地里干了一天的 ...
- golang 方法接收者
[定义]: golang的方法(Method)是一个带有receiver的函数Function,Receiver是一个特定的struct类型,当你将函数Function附加到该receiver, 这个 ...
- Kubernetes client-go 源码分析 - ListWatcher
概述ListWatch 对象的创建GetterListWatchList() & Watch() 概述 源码版本信息 Project: kubernetes Branch: master La ...
- Nastran的应变方向
问题 近日使用Nastran做一个算例,在计算频响时发现:位移场是连续的,而应变场不连续.以某一频率处应变场为例,其上表面X.Y方向应变场分布如下图.此处关闭了云图的插值,所显示的为单元的应变,因此云 ...
- dubbo容错机制
dubbo的容错机制 Failover Cluster(默认) 失败自动切换,当出现失败,重试其它服务器.通常用于读操作,但重试会带来更长延迟. Failfast Cluster 快速失败,只发起一次 ...