asp.net

C# 自定义特性 Attribute

2023-03-11

一、C# 自定义特性 Attribute

特性 Attribute

A:就是一个类,直接继承 / 间接继承 Attribute

B:特性可以在后期反射中处理,特性本身是没有什么 * 用的

C:特性会影响编译和运行时功能


二、自定义 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)}");  

          }

      } 

}