C# 自定義特性Attribute


一、特性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; }
    }
}
View Code

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; }
    }
}
View Code

我們標識了這些特性到底要怎么使用呢?

文章的開始就已經說了特性可以在后期反射中處理,特性本身是沒有什么*用的

那么我們通過反射如何去使用特性

接下來以上面給出的代碼去實現,定義了一個擴展方法

用到了反射和泛型等知識,如果有小伙伴不懂可參考以下文章
反射: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:支持規則的隨意擴展

運用了這個特性校驗后,就不用再每個地方再分別寫校驗的邏輯,簡單易用!

參考文章:https://www.cnblogs.com/loverwangshan/p/10153832.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM