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 }
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 字符编码:从基础到乱码解决