一、特性Attribute和注釋有什么區別
特性Attribute
A:就是一個類,直接繼承/間接繼承Attribute
B:特性可以在后期反射中處理,特性本身是沒有什么*用的
C:特性會影響編譯和運行時功能
注釋
A:就是對代碼的解釋和說明,其目的是讓人們能夠更加輕松地了解代碼。注釋是編寫程序時,寫程序的人給一個語句、程序段、函數等的解釋或提示,能提高程序代碼的可讀性
B:注釋不能后期處理
二、自定義Attribute特性的使用
自定義Attribute特性的語法
其實特性就是一個類,直接繼承或者間接的繼承Atrribute的就是一個特性
首先聲明特性,以下面的代碼舉個例子
//直接繼承Attribute public class CustomAttribute : Attribute { public string Name { get; set; } public CustomAttribute() { Console.WriteLine($"{this.GetType().Name} 無參構造函數"); } public CustomAttribute(string name) { Console.WriteLine($"{this.GetType().Name} string 參數構造函數"); Name = name; } } //間接繼承Attribute public class CustomAttributeChild : CustomAttribute { public CustomAttributeChild() { Console.WriteLine($"{this.GetType().Name} 無參構造函數"); } public CustomAttributeChild(string name) : base(name) { Console.WriteLine($"{this.GetType().Name} string 參數構造函數"); } }
特性的使用
首先我們准備一個自定義特性DisplayName
自定義特性
/// <summary> /// 是給屬性和字段 提供一個額外信息 /// AllowMultiple特性影響編譯器,AttributeTargets修飾的對象 AllowMultiple:能否重復修飾 Inherited:是否可繼承 /// 可以指定屬性和字段 /// </summary> namespace Ramon.Common.CustomAttribute { [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false, Inherited = false)] public sealed class DisplayNameAttribute : Attribute { public string Name { get; } public DisplayNameAttribute(string sValue) { Name = sValue; } } }
在CompanyModel的屬性上使用DisplayName的特性
BaseModel
namespace Ramon.Common.Framework { public class BaseModel { public int Id { get; set; } } }
CompanyModel
namespace Ramon.Model.Model { public class CompanyModel : BaseModel { [DisplayName("公司名稱")] public string Name { get; set; } [DisplayName("創建日期")] public DateTime CreateTime { get; set; } [DisplayName("創建人Id")] public int CreatorId { get; set; } [DisplayName("最后修改人Id")] public int? LastModifierId { get; set; } [DisplayName("最后修改時間")] public DateTime? LastModifyTime { get; set; } } }
我們標識了這些特性到底要怎么使用呢?
文章的開始就已經說了特性可以在后期反射中處理,特性本身是沒有什么*用的
那么我們通過反射如何去使用特性
接下來以上面給出的代碼去實現,定義了一個擴展方法
用到了反射和泛型等知識,如果有小伙伴不懂可參考以下文章
反射:https://www.cnblogs.com/Ramon-Zeng/p/10189097.html
泛型:https://www.cnblogs.com/Ramon-Zeng/p/10172818.html
public static class BaseModelExtenstion { public static void ConsoleEntity<TEntity>(this TEntity tEntity) where TEntity : BaseModel { Type type = tEntity.GetType(); PropertyInfo[] propInfos = type.GetProperties(); foreach (var prop in propInfos) { string parameterName = prop.Name; if (prop.IsDefined(typeof(DisplayNameAttribute), false)) { DisplayNameAttribute attribute = (DisplayNameAttribute)prop.GetCustomAttribute(typeof(DisplayNameAttribute), false); parameterName = attribute.Name.IsNullOrWhiteSpace() ? prop.Name : attribute.Name; } Console.WriteLine($"{parameterName}:{prop.GetValue(tEntity)}"); } } }
代碼調用
class Program { static void Main(string[] args) { CompanyModel companyModel = new CompanyModel() { Id = 1, Name = "Ramon----集團", CreateTime = DateTime.Now, CreatorId = 1, }; companyModel.ConsoleEntity(); } }
結果

二:特性的運用范圍
特性運用范圍極其廣,框架中我們看到上面的總結就曉得了,下面的我總結了以下幾個地方也可以使用特性
1:數據展示 不想展示屬性名字,而是用中文描述
2:想指定哪個是主鍵,哪個是自增
3:別名 數據庫里面叫A 程序是B,怎么映射等
然后特性還可以校驗一些數據字段等,下面我寫個例子,以便更加容易理解:
1:先創建數據校驗的特性
View Code
2:再一個實體類上面的字段增加特性
View Code
3:寫下面的方法,使特性生效
View Code
4:應用判斷時如下:
View Code
這樣就完成了數據校驗,特性校驗的特點,總結得到了如下三點:
1:可以校驗多個屬性
2:可以支持多重校驗
3:支持規則的隨意擴展
運用了這個特性校驗后,就不用再每個地方再分別寫校驗的邏輯,簡單易用!
