• C#--特性的运用试验


    以下是学习笔记:

    一,特性运用试验(一)

    需求1:传统的代码

    有这样一个用户状态的枚举类型:

    namespace _015_特性.EnumExtend
    {
        /// <summary>
        /// 枚举:用户的状态
        /// </summary>
        public enum UserState
        {
            /// <summary>
            /// 正常
            /// </summary>
            Normal=0,
            /// <summary>
            /// 冻结
            /// </summary>
            Frozen=1,
            /// <summary>
            /// 删除
            /// </summary>
            Deleted=2
        }
    }
    

      

    如果想要知道用户的状态,代码这样写:

                UserState userState = UserState.Frozen;
                if (userState == UserState.Normal)
                {
                    Console.WriteLine("正常");
                }
                else if (userState == UserState.Frozen)
                {
                    Console.WriteLine("冻结");
                }
                else if (userState == UserState.Deleted)
                {
                    Console.WriteLine("删除");
                }
    

      

    上面的代码存在这样的问题:

    如果状态要改变(正常,删除,冻结,,),改代码就非常的费劲,每次都要判断很多次

    需求1:运用特性后的代码思路

    【1】,先定义一个特性

    namespace _015_特性.EnumExtend
    {
        //自定义Attribute,特性上还可以加特性
        [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
        //参数1:可以被哪些情况下使用,如果是All就是被所有情况下都可以用。
        //参数2:是否可以标记多个特性
        //参数3:是否可以被继承
        public class RemarkAttribute:Attribute
        {
           /// <summary>
           /// 状态特性
           /// </summary>
           /// <param name="remark"></param>
            public RemarkAttribute(string remark)
            {
                this.Remark = remark;
            }
    
            public string Remark { get;private set; }
        }
    }
    

      

    【2】,特性定义好了之后,标记特性

    namespace _015_特性.EnumExtend
    {
        /// <summary>
        /// 枚举:用户的状态
        /// </summary>
        public enum UserState
        {
            /// <summary>
            /// 正常
            /// </summary>
            [Remark("正常")]
            Normal=0,
            /// <summary>
            /// 冻结
            /// </summary>
            [Remark("冻结")]
            Frozen = 1,
            /// <summary>
            /// 删除
            /// </summary>
            [Remark("删除")]
            Deleted = 2
        }
    }
    

      

    【3】写一个调用特性方法的类

    namespace _015_特性.EnumExtend
    {
        /// <summary>
        /// 特性调用的类,用来调用特性的
        /// </summary>
        public class AttributeInvoke
        {
            public string GetRemark(UserState userState)
            {
                Type type = userState.GetType();//获取到传过来的类型
                var fileId = type.GetField(userState.ToString());//根据参数这个值找到具体的字段
                if(fileId.IsDefined(typeof(RemarkAttribute),true)) //查找字段有没有有定义RemarkAttribute这个特性,
                {
                    RemarkAttribute remarkAttribute =
                        (RemarkAttribute) fileId.GetCustomAttribute(typeof(RemarkAttribute), true);
                    return remarkAttribute.Remark;//如果找到了,就返回这个特性的属性
    
                }
                else
                {
                    return userState.ToString();//如果找不到,就返回传过来的这个值
                }
            }
        }
    }
    

      

    【4】在主程序中调用

                UserState userState2 = UserState.Frozen;
                AttributeInvoke attributeInvoke=new AttributeInvoke();
                Console.WriteLine(attributeInvoke.GetRemark(userState2));
    

      

    改用特性的好处总结:不用if else的判断了,直接把userState2当做参数传入方法attributeInvoke.GetRemark(userState2)就可以啦。

    总结上面的过程:定义特性--标记特性--调用(需要用到发射的技术)

    二,特性运用试验(二),特性验证

    【1】定义带特性的抽象类

    namespace _015_特性.ValidateExtend
    {
        /// <summary>
        /// 带有抽象方法的抽象类
        /// </summary>
        public abstract class AbstractValidateAttribute:Attribute
        {
            /// <summary>
            /// 验证数据的方法
            /// </summary>
            /// <param name="objValue"></param>
            /// <returns></returns>
            public abstract bool Validate(object objValue);
        }
    }
    

      

    【2】写三个实现抽象类的实现验证类

    1,

    namespace _015_特性.ValidateExtend
    {
        [AttributeUsage(AttributeTargets.Property)]
        public class LongAttribute : AbstractValidateAttribute
        {
            private long _Long = 0;
    
            public LongAttribute(long phoneLength)
            {
                this._Long = phoneLength;
            }
            /// <summary>
            /// 检验手机号是否为11位
            /// </summary>
            /// <param name="objValue"></param>
            /// <returns></returns>
            public override bool Validate(object objValue)
            {
                return objValue != null && objValue.ToString().Length == 11;
    
            }
        }
    }
    

      

    2,

    namespace _015_特性.ValidateExtend
    {
        public class RequriedAttribute : AbstractValidateAttribute
        {
            /// <summary>
            /// 检验值是否为空
            /// </summary>
            /// <param name="objValue"></param>
            /// <returns></returns>
            public override bool Validate(object objValue)
            {
               return objValue != null && !string.IsNullOrWhiteSpace(objValue.ToString());
            }
        }
    }
    

      

    3,

    namespace _015_特性.ValidateExtend
    {
        [AttributeUsage(AttributeTargets.Property)]
        public class StringLengthAttribute : AbstractValidateAttribute
        {
            private int _Min = 0;
            private int _Max = 0;
    
            public StringLengthAttribute(int min,int max)
            {
                this._Min = min;
                this._Max = max;
            }
            /// <summary>
            /// 验证字符串的长度
            /// </summary>
            /// <param name="objValue"></param>
            /// <returns></returns>
            public override bool Validate(object objValue)
            {
              return  objValue != null && objValue.ToString().Length >= this._Min && objValue.ToString().Length <= this._Max;
            }
        }
    }
    

      

    【3】,写一个调用方法的类

    namespace _015_特性.ValidateExtend
    {
        public static class AttributeExtend
        {
            /// <summary>
            /// 调用特性的方法的类(扩展方法)
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="t"></param>
            /// <returns></returns>
            public static bool Validate<T>(this T t)
            {
                Type type = t.GetType();//找到t参数的类型
                foreach (var property in type.GetProperties())//从类型里面查找遍历所有的属性
                {
                    if (property.IsDefined(typeof(AbstractValidateAttribute), true)) //查找属性有没有被定义AbstractValidateAttribute特性
                    {
                        object objValue = property.GetValue(t);//获取属性的值
                        foreach (AbstractValidateAttribute attribute in property.GetCustomAttributes(typeof(AbstractValidateAttribute), true))
                        {
                            if (!attribute.Validate(objValue))//如果成功了以后就继续验证,否则就直接返回
                            {
                                return false;
                            }
                        }
                    }
                }
    
                return true;
            }
        }
    }
    

      

    【4】要验证的实体类,并标记特性

    namespace _015_特性.ValidateExtend
    {
        public class Student
        {
            public int Id { get; set; }
            [Requried]
            [StringLength(5,10)]
            public string StudentName { get; set; }
            [Requried]
            [Long(11)]
            public long PhoneNumber { get; set; }
        }
    }
    

      

    【5】在主程序中调用

                Student student = new Student()
                {
                    Id = 1,
                    PhoneNumber = 186684806622,
                    StudentName = "jason cai"
                };
                if (student.Validate())
                {
                    Console.WriteLine("验证成功");
                }
                else
                {
                    Console.WriteLine("验证失败");
                }
    

      

  • 相关阅读:
    在Vue构建的SPA网页里 刷新的话,显示404页面
    springboot2.x 设置404页面
    关于Typora不显示PicGo.app的问题
    DBeaver中table插入新的数据
    DBeaver修改table的column名字
    Zeal
    Android Studio 快速创建 Toast
    使用VSCode调试单个JavaScript文件
    使用maven打包普通的java项目
    在命令行界面实现彩色字符输出 -- 并且介绍和这个相关的比较好用的java类库
  • 原文地址:https://www.cnblogs.com/baozi789654/p/14233002.html
Copyright © 2020-2023  润新知