zoukankan      html  css  js  c++  java
  • 学习笔记: 特性Attribute详解,应用封装

    ///
    /// 特性:中括号声明
    ///
    /// 错觉:每一个特性都可以带来对应的功能
    ///
    /// 实际上特性添加后,编译会在元素内部产生IL,但是我们是没办法直接使用的,
    /// 而且在metadata里面会有记录
    ///
    /// 特性,本身是没用的
    /// 程序运行的过程中,我们能找到特性,而且也能应用一下
    /// 任何一个可以生效的特性,都是因为有地方主动使用了的


    image


    一个应用场景:  可以用特性标注枚举值,以便 程序用到该枚举的 中文

    public enum UserState
         {
             /// <summary>
             /// 正常
             /// </summary>
             [Remark("正常")]
             Normal = 0,//左边是字段名称  右边是数据库值   哪里放描述?  注释
             /// <summary>
             /// 冻结
             /// </summary>
             [Remark("冻结")]
             Frozen = 1,
             /// <summary>
             /// 删除
             /// </summary>
             //[Remark("删除")]
             Deleted = 2
         }
         //枚举项加一个描述   实体类的属性也可以Display 
         //别名   映射 
         public class RemarkAttribute : Attribute
         {
             public RemarkAttribute(string remark)
             {
                 this._Remark = remark;
             }
             private string _Remark = null;
             public string GetRemark()
             {
                 return this._Remark;
             }
         }


    public static class RemarkExtension
    {
         public static string GetRemark(this Enum value)
         {

            Type type = value.GetType();
             FieldInfo field = type.GetField(value.ToString());
             if (field.IsDefined(typeof(RemarkAttribute),true)){
                 RemarkAttribute attribute = (RemarkAttribute)field.GetCustomAttribute(typeof(RemarkAttribute));
                 return attribute.GetRemark();
             }
             else
             {
                 return value.ToString();
             }
         }

    }

    static void Main(string[] args){

        Console.WriteLine(UserState.Frozen.GetRemark());
         Console.WriteLine(UserState.Deleted.GetRemark());

    }

    应用场景: 展示在页面的表格,每列的字段名 怎么展示? 写死吗? MVC中的 Display即为了解决该问题

                  做数据检查 , 比如 注册时用户名长度检查,qq检查


    MVC中 常用的 model.isvalidate()  简单实现如下

    核心: 自定义的attr都继承抽象类, 只需在main中调用 扩展方法, 所有实现了 该抽象特性类的的特性 都会调用 重写的validate方法 进行自己的逻辑验证


    public class Student
         {
             [CustomAttribute]
             public int Id { get; set; }
             [Leng(5, 10)]//还有各种检查
             public string Name { get; set; }
             [Leng(20, 50)]
             public string Accont { get; set; }

            [Long(10000, 999999999)]
             public long QQ { get; set; }

            [CustomAttribute]
             public void Study()
             {
                 Console.WriteLine($"这里是{this.Name}跟着Eleven老师学习");
             }

            [Custom()]
             [return: Custom()]
             public string Answer([Custom]string name)
             {
                 return $"This is {name}";
             }
         }

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


         public static class ValidateExtension
         {
             public static bool Validate(this object obj)
             {
                 Type type = obj.GetType();
                 foreach (var prop in type.GetProperties())
                 {

                    if (prop.IsDefined(typeof(AbstractValidateAttribute), true))
                     {
                         object[] attributeArray = prop.GetCustomAttributes(typeof(AbstractValidateAttribute), true);
                         foreach (AbstractValidateAttribute attribute in attributeArray)
                         {
                             if (!attribute.Validate(prop.GetValue(obj)))
                             {
                                 return false;//表示终止
                             }
                         }
                     }

                     //if (prop.IsDefined(typeof(LongAttribute), true))
                     //{
                     //    var attribute = (LongAttribute)prop.GetCustomAttribute(typeof(LongAttribute), true);
                     //    if (!attribute.Validate(prop.GetValue(obj)))
                     //        return false;
                     //}

                    //if (prop.IsDefined(typeof(LengAttribute), true))
                     //{
                     //    LengAttribute attribute = (LengAttribute)prop.GetCustomAttribute(typeof(LengAttribute), true);
                     //    if (!attribute.Validate(prop.GetValue(obj)))
                     //        return false;
                     //}
                 }

                return false;
             }
         }

        public class LongAttribute: AbstractValidateAttribute
         {
             private long _Min, _Max = 0;
             public LongAttribute(long min,long max)
             {
                 this._Min = min;
                 this._Max = max;
             }

            public override bool Validate(object value)
             {
                 if(value!=null && !string.IsNullOrWhiteSpace(value.ToString()))
                 {
                    if( long.TryParse(value.ToString(), out long lResult))
                     {
                         if (lResult > _Min && lResult < _Max)
                             return true;
                     }

                }
                 return false;
             }
         }

        public class LengAttribute : AbstractValidateAttribute
         {
             private long _Min, _Max = 0;
             public LengAttribute(long min, long max)
             {
                 this._Min = min;
                 this._Max = max;
             }

            public override bool Validate(object value)
             {
                 if (value != null && !string.IsNullOrWhiteSpace(value.ToString()))
                 {
                     int length = value.ToString().Length;
                     if (length > _Min && length < _Max)
                         return true;

                }
                 return false;
             }
         }

  • 相关阅读:
    【C++】对象模型
    【C++多线程】读写锁shared_lock/shared_mutex
    【C++多线程】共享数据的初始化保护
    【C++多线程】共享数据保护
    【C++多线程】lock_guard<T>类和unique_lock<T>类
    【C++多线程】转移线程所有权
    【C++ 】std::ref()和std::cref()
    【C++多线程】传递参数
    【C++多线程】detach()及注意
    linux 打开CHM文件
  • 原文地址:https://www.cnblogs.com/xtxtx/p/9136614.html
Copyright © 2011-2022 走看看