C#特性的介绍及应用场景
1.特性的任务:特性就是为了支持对象添加一些自我描述的信息,不影响类封装的前提添加额外信息。如果你用这个信息,那特性就有用;如果你不需要这个信息,那么这个特性就没用。
2.特性的基类:Attribute。例如:Obsolete特性,提出警告信息或错误信息,特性可以影响编译、影响运行。
3.特性类通常用Attribute结尾,在使用的时候可以用全称,也可以去掉这个结尾,也可以加上小括号显示调用构造函数,如果不加小括号默认调用无参构造函数,也可以在括号内直接给属性或字段赋值。
4.特性往往只能修饰一个对象一次,需要设置属性的属性的时候,需要给属性添加AttributeUsage属性,可以用来设置:是否允许多次修饰、修饰对象的类别(类or字段等)
5.DLL文件=IL中间语言+metadata元数据,特性信息会被编译到元数据中。
6.使用场景
6.1为类或成员添加描述信息,然后在使用的时候拿到该信息。
/// <summary> /// 描述实体映射的数据表 /// </summary> public class TableNameAttribute : Attribute { public TableNameAttribute() { } public string TableName { get; set; } } [TableName(TableName = "Users")] public class User { public int Id { get; set; } public string Name { get; set; } } class Program { public static void Main(string[] args) { User user = new User(); Type t = user.GetType(); object[] customAttrs = t.GetCustomAttributes(true); for (int i = 0; i < customAttrs.Length; i++) { if (customAttrs[i] is TableNameAttribute) { TableNameAttribute tnAttr = (TableNameAttribute)customAttrs[i]; Console.WriteLine(tnAttr.TableName); } } } }
6.2 做数据验证
public class IntValidateAttribute : Attribute { /// <summary> /// 最小值 /// </summary> private int minValue { get; set; } /// <summary> /// 最大值 /// </summary> private int maxValue { get; set; } /// <summary> /// 构造函数 /// </summary> /// <param name="minValue"></param> /// <param name="maxValue"></param> public IntValidateAttribute(int minValue, int maxValue) { this.minValue = minValue; this.maxValue = maxValue; } /// <summary> /// 检验值是否合法 /// </summary> /// <param name="checkValue"></param> /// <returns></returns> public bool Validate(int checkValue) { return checkValue >= minValue && checkValue <= maxValue; } } public class User { [IntValidate(1, 10)] public int Id { get; set; } public string Name { get; set; } } public class BaseDal { public static string Insert<T>(T model) { Type modelType = typeof(T); //获取类型的所有属性 PropertyInfo[] propertyInfos = modelType.GetProperties(); bool boIsCheck = true; //循环所有属性 foreach (var property in propertyInfos) { //获取属性的所有特性 object[] attrs = property.GetCustomAttributes(true); if (property.PropertyType.Name.ToLower().Contains("int")) { foreach (var attr in attrs) { if (attr is IntValidateAttribute) { IntValidateAttribute intValidate = (IntValidateAttribute)attr; //执行特性的验证逻辑 boIsCheck = intValidate.Validate((int)property.GetValue(model)); } } } if (!boIsCheck) { break; } } if (boIsCheck) { return "验证通过,插入数据库成功"; } else { return "验证失败"; } } } class Program { public static void Main(string[] args) { string msg = BaseDal.Insert<User>(new User() { Id = 123, Name = "lvcc" }); Console.WriteLine(msg); } }
6.3 添加说明信息并获取,同6.1
/// <summary> /// 备注特性 /// </summary> public class RemarkAttribute : Attribute { private string Remark { get; set; } public RemarkAttribute(string Remark) { this.Remark = Remark; } public string GetRemark() { return this.Remark; } } public enum ESex { [Attributes.Remark("男的")] boy=1 , [Attributes.Remark("女的")] girl =2 } /// <summary> /// 提供扩展方法 /// </summary> public static class EnumExtension { public static string GetRemark(this Enum model) { if (model is ESex) { Type type = typeof(ESex); FieldInfo fi = type.GetField(model.ToString()); object[] attributes = fi.GetCustomAttributes(true); foreach (var attr in attributes) { if (attr is RemarkAttribute) { RemarkAttribute remark = (RemarkAttribute)attr; return remark.GetRemark(); } } } return string.Empty; } } class Program { public static void Main(string[] args) { Console.WriteLine(ESex.boy.GetRemark()); } }
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
· C++代码改造为UTF-8编码问题的总结
· 实操Deepseek接入个人知识库
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· 【.NET】调用本地 Deepseek 模型
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
· 上周热点回顾(2.17-2.23)