美文网首页
C#特性Attribute详解及使用场景

C#特性Attribute详解及使用场景

作者: 浅谈码生活 | 来源:发表于2020-08-24 14:02 被阅读0次

    Attribute定义:特性其实是一个类,是直接/间接继承自Attribute,约定俗成是以Attribut结尾,在标记的时候以[]包裹,尾部的Attribut可以省略掉;
    Attribute作用:可以增加额外信息,增加额外功能,但让特性生效需要使用反射;
    Attribute的使用场景:MVC,WCF,ORM等;
    多说不宜,直接上代码:

    定义Attribute:

     /// <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;
            } 
        }
    }
    

    利用反射获取Attribute信息并执行方法:

    public static void ReflectionArrtibute<T>(T t) where T : Class
    {
          Type type = t.GetType();//通过参数来获取Type类型
          if (type.IsDefined(typeof(CustomAttribute),true)) //反射调用特性,记得一定要先判断,然后再获取
          { 
              foreach (CustomAttribute attribute in type.GetCustomAttributes()) //把所有标记的特性都实例化了
              {
                  Console.WriteLine($"attribute.Id={attribute.Id}");
                  Console.WriteLine($"attribute.Name={attribute.Name}");
                  attribute.Do();
              }
              ///循环获取所有的属性上标记的特性,调用特性中的元素
              foreach (PropertyInfo prop in type.GetProperties())
              { 
                  if (prop.IsDefined(typeof(CustomAttribute), true))
                  {
                      foreach (CustomAttribute attribute in prop.GetCustomAttributes()) //把所有标记的特性都实例化了
                      {
                          Console.WriteLine($"attribute.Id={attribute.Id}");
                          Console.WriteLine($"attribute.Name={attribute.Name}");
                          attribute.Do();
                      }
                  }
              }
              ///循环获取所有的字段上标记的特性,调用特性中的元素
              foreach (FieldInfo field in type.GetFields())
              {
                  if (field.IsDefined(typeof(CustomAttribute), true))
                  {
                      foreach (CustomAttribute attribute in field.GetCustomAttributes()) //把所有标记的特性都实例化了
                      {
                          Console.WriteLine($"attribute.Id={attribute.Id}");
                          Console.WriteLine($"attribute.Name={attribute.Name}");
                          attribute.Do();
                      }
                  }
               }
              ///循环获取所有方法上标记的特性,调用特性中的元素
              foreach (MethodInfo method in type.GetMethods())
              {
                  if (method.IsDefined(typeof(CustomAttribute), true))
                  {
                      foreach (CustomAttribute attribute in method.GetCustomAttributes()) //把所有标记的特性都实例化了
                      {
                          Console.WriteLine($"attribute.Id={attribute.Id}");
                          Console.WriteLine($"attribute.Name={attribute.Name}");
                          attribute.Do();
                      }
                  }
              } 
    }
    

    将枚举值的中文扩展信息添加到Attribute:

    //新增ExplainAttribute
    [AttributeUsage( AttributeTargets.All,AllowMultiple =true,Inherited =true)]
    public class ExplainAttribute :Attribute
    {
            public string Explain { get; private set; } 
            public ExplainAttribute(string explain)
            {
                this.Explain = explain;
            } 
    }
    //创建枚举
    public enum GameState
    {
            [ExplainAttribute("开始")]
            Start,
            [ExplainAttribute("暂停")]
            Stop,
            [ExplainAttribute("继续")]
            GoOn
    }
    //获取Attribute信息
    public static class ExplainExtension
    {
            public static string GetExplain(this Enum @enum)
            {
                Type type = @enum.GetType();
    
                FieldInfo field = type.GetField(@enum.ToString());
    
                if (field != null)
                {
                    if (field.IsDefined(typeof(ExplainAttribute), true))
                    {
                        ExplainAttribute attribute = field.GetCustomAttribute<ExplainAttribute>();
    
                        return attribute.Explain;
                    }
                }
                return @enum.ToString();
            }
     }
    

    使用Attribute验证输入信息:

    //定义用于验证的Attribute
     [AttributeUsage(AttributeTargets.Property)]
     public class MobileNumAtrribute : AbstractValidateAttribute
     {
            public int Count { get; private set; }
    
            public MobileNumAtrribute(int count)
            {
                if (count<=0)
                {
                    throw new Exception("手机号长度不可能为负数");
                }
                Count = count;
            }
            public override bool Validate(object mobileNum)
            { 
                return mobileNum != null && mobileNum.ToString().Length == Count; 
            } 
     }
    //定义需要验证的类
     public class Student
     {
            public string Description; 
            public string QQ { get; set; }
            [MobileNumAtrribute(11)]
            public long MobileNum { get; set; } 
     }
    //验证
    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;
                        }
                }
                return true;
    }
    

    相关文章

      网友评论

          本文标题:C#特性Attribute详解及使用场景

          本文链接:https://www.haomeiwen.com/subject/gwngjktx.html