关于特性的一些理解

特性,是一个类,声明的时候默认以Attribute 结尾,同时继承自Attribute抽象类

应用特性 ,以 [MyAttribute] 标记在类,或者类的内部成员上;(标记特性时,如果是以Attribute结尾则可以省略掉)

特性和注释的区别

 注释在类编译后是不存在的,而特性由于他的本质是一个类,所以在编译之后是存在的通过反射就可以拿到特性里边的属性,方法;

通常特性可以标注在类的内部的任何成员上,

标记特性时,就是在调用特性类的构造函数

默认是不可以重复标记属性的

AttributeUsage:也是一个特性,是用来约束特性的特性

AttributeTargets 指定当前特性只能标记在某个地方

AllowMultiple 是否可以重复标记

Inherited 特性是否可以被继承 默认是

//表示只能标记到属性上,可以多次标记,可以被继承 

 [AttributeUsage(AttributeTargets.Property,AllowMultiple =true,Inherited =true)]

public class RequiredAttribute : AbstractAttribute

    {

     }

如何使用特性,因为特性本身也是一个类所以调用它要使用反射,在使用反射调用特性的时候可以把标记在任何地方的特性都获取到;

  1.//新建一个枚举类

    public enum Myenum

    {

        n=1,

        f=2,

        c=3

    }

  2. /// <summary>

    /// 新建一个Attribute标记类用来标记Enum,

    /// </summary>

     [AttributeUsage( AttributeTargets.All,AllowMultiple =true, Inherited =true)]//最好给特性设定能标记的范围

    public class MyEnumAttribute:Attribute

    {

        /// <summary>

        /// 前边有提到过调用特性就是调用他的构造函数

        /// </summary>

        public string Description { get; set; }

        public MyEnumAttribute(string _Description)

        {

         this.Description= _Description;

        }

        public string GetRemark()

        {

            return this.Description;

        }

    }

 3.//实例化一个枚举

            Myenum myenum = new Myenum();

            //获取枚举中的某一个字段

            var type = myenum.GetType().GetField("n");

            //获取字段的标记

            var atts = type.GetCustomAttribute<MyEnumAttribute>();

            //调用特性中的放法

            var rmk = atts.GetRemark();

            //获取赋值给特性的值

            Console.WriteLine(rmk);

 //封装一个扩展调用方式

public static class MyAttrMouthed

    {

   

    public static string com(this Myenum myenum)

        {

            var type = myenum.GetType();

            var myenumname = myenum.ToString();

            var myenfild = type.GetField(myenumname);

            if (myenfild.IsDefined(typeof(MyEnumAttribute), true))

            {

                var attr = myenfild.GetCustomAttribute<MyEnumAttribute>();

                var result = attr.GetRemark();

                return result;

            }

            return "不存在标记类";

        }

    }

//封装一个扩展调用方式     

Myenum myenum1 = Myenum.f;

            var cw=  myenum1.com();

            Console.WriteLine(cw);

//两种不同的调用方法 ,表格内为封装调用方式

除此之外 特性还可以应用于字段验证;

这里要有一个封装的思想,首先判断每个字段是否合法,就需要考虑有非常多种类的字段(有int,有string,有doubule等等)

    类1

//只能标记到字段上

    [AttributeUsage( AttributeTargets.Property,AllowMultiple=true, Inherited =true)]

    public abstract class CommonAttribute:Attribute

    {

        /// <summary>

        /// 父类公共验证的方法,需要传递要验证的参数

        /// </summary>

        /// <param name="value"></param>

        /// <returns></returns>

        public abstract ResultMessage validation(object value);

    

    }

类2

public class ProptyLingthAttribute : CommonAttribute

    {

        public int Min { get; set; }

        public int Max { get; set; }

        public ProptyLingthAttribute(int min, int max)

        {

            Min = min;

            Max = max;

        }

        public override ResultMessage validation(object value)

        {

           var valuestring=value.ToString();

            if(!string.IsNullOrEmpty(valuestring))

            {

                if (valuestring.Length <= Min || valuestring.Length >= Max)

                {

                    return new ResultMessage() { Success = 2, Message = "字符长度不正确" };

                }

            }

            return new ResultMessage() { Success = 1, Message = "字符不能为空" };

        }

    }

类3

/// <summary>

    /// 结果返回包装

    /// </summary>

    public class ResultMessage

    {

        public string? Message { get; set; }

        public int Success { get; set; }

    }

类4

 /// <summary>

    /// 利用反射调用特性里的方法实现判断

    /// </summary>

    public static class ValidateMethod

    {

        public static ResultMessage ValidateMeaage<T>(this T t)where T : class

        {

          Type  type= typeof(T);

          PropertyInfo[] propertieyinfors= type.GetProperties();

            foreach (var propertieyinfor in propertieyinfors)

            {

                var value = propertieyinfor.GetValue(t,null);

             var customs=   propertieyinfor.GetCustomAttributes<CommonAttribute>();

                foreach (var custom in customs)

                {

                  return   custom.validation(value);

                }

            }

            return new ResultMessage() { Success = 1, Message = "错误" };

        }

    }

调用

var ceshi= ValidateMethod.ValidateMeaage(new Class1() { Name = "wulikao" });

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值