C#特性Attribute

特性其实是一个类,是直接/间接继承自Attribute

约定俗成是以Attribut结尾,在标记的时候以[]包裹,尾部的Attribut可以省略掉;

通过反编译之后,在中间语言IL中我们发现标记特性的元素内部都生成了一个.Custom,但是我们调用不了;

 

自定义特性

 /// <summary>
    /// 自定义特性
    /// AllowMultiple =true:标记在特性上的特性,其实是对特性的一种约束;
    /// Inherited =true:约束当前特性是否可以继承
    /// AttributeTargets.All:当前特性可以标记在所有的元素上
    /// AttributeUsage:在定义特性的时候,对特性的一种约束,老师也建议大家自己以后在声明特性的时候,加上这个,就相当于明确告诉别人,我这个特性只能标记在哪些地方;     /// </summary>
    [AttributeUsage(AttributeTargets.All, AllowMultiple = true, Inherited = true)]
    public class CustomAttribute : Attribute
    {

        public CustomAttribute()
        {

        }

        public CustomAttribute(int id)
        {

        }
        public CustomAttribute(string name)
        {

        }

        public CustomAttribute(int id,string name)
        {
            this.Id = id;
            this.Name = name;
        }


        public string Description;

        public int Id { get; set; }

        public string Name { get; set; }
         
        public int Do()
        {
            return 1;
        } 
    }

    public class CustomAttributeChild : CustomAttribute
    {
    }

 

 

 

通过特性获取枚举描述

 [AttributeUsage(AttributeTargets.Field)]
    public class RemarkAttribute : Attribute
    {
        public string Remark { get; private set; }

        public RemarkAttribute(string remark)
        {
            this.Remark = remark;
        }
    }

 

/// <summary>
    /// 在数据库中存在一个字段对应的就是这个枚举,数据库中存储的其实是数字,0,1,2
    /// </summary>
    //[RemarkAttribute]
    public enum UserStuta
    {
        /// <summary>
        /// 正常状态
        /// </summary>
        [RemarkAttribute("正常")]
        Normal = 0,
        /// <summary>
        /// 已冻结
        /// </summary
        [RemarkAttribute("已冻结")]
        Frozen = 1,
        /// <summary>
        /// 已删除
        /// </summary>
        [RemarkAttribute("已删除")]
        Deleted = 2
    }

 

 public static class RemarkExtension
    {
        public static string GetRemark(this Enum @enum) //扩展方法
        {
            Type type = @enum.GetType();
            FieldInfo? fileInfo = type.GetField(@enum.ToString());
            if (fileInfo != null)
            {
                if (fileInfo.IsDefined(typeof(RemarkAttribute), true))
                {
                    RemarkAttribute remarkAttribute = (RemarkAttribute)fileInfo.GetCustomAttribute(typeof(RemarkAttribute), true);
                    return remarkAttribute.Remark;
                }
            }
            return @enum.ToString();
        }
    }

调用

 var normal = UserStuta.Normal;
 string strnormal = RemarkExtension.GetRemark(normal); //获取枚举描述

 

通过特性校验数据

 public static bool Validate<T>(T t)
        { 
            Type type = t.GetType();
            foreach (PropertyInfo prop in type.GetProperties())
            {
                ///验证手机号长度
                //if (prop.IsDefined(typeof(MobileNumAtrribute), true))
                //{
                //    object oValue = prop.GetValue(t); 
                //    MobileNumAtrribute atrribute = prop.GetCustomAttribute<MobileNumAtrribute>(true);
                //    if (!atrribute.Validate(oValue))
                //    {
                //        return false;
                //    } 
                //} 
                /////这就是验证QQ
                //if (prop.IsDefined(typeof(QQAttribute), true))
                //{
                //    object oValue = prop.GetValue(t);
                //    QQAttribute atrribute = prop.GetCustomAttribute<QQAttribute>(true);
                //    if (!atrribute.Validate(oValue))
                //    {
                //        return false;
                //    } 
                //} 
                //如果后续还需要再加一个验证呢?那岂不是 又要修改代码?
                //这样做是坑,抽象~~ 
                if (prop.IsDefined(typeof(AbstractValidateAttribute), true))
                {
                    object oValue = prop.GetValue(t);
                    AbstractValidateAttribute atrribute = prop.GetCustomAttribute<AbstractValidateAttribute>(true);
                    if (!atrribute.Validate(oValue))
                    {
                        return false;
                    }
                }

            }
            return true;
        }
public abstract class AbstractValidateAttribute : Attribute
{
public abstract bool Validate(object value);


 

 

bool bResult = Validate<StudentVip>(vip);

 

posted @ 2022-09-03 17:16  Tiye529  阅读(47)  评论(0)    收藏  举报