///

/// 特性:中括号声明

///

/// 错觉:每一个特性都可以带来对应的功能

///

/// 实际上特性添加后,编译会在元素内部产生IL,但是我们是没办法直接使用的,

/// 而且在metadata里面会有记录

///

/// 特性,本身是没用的

/// 程序运行的过程中,我们能找到特性,而且也能应用一下

/// 任何一个可以生效的特性,都是因为有地方主动使用了的

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

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

学习笔记: 特性Attribute详解,应用封装的更多相关文章

  1. expect学习笔记及实例详解【转】

    1. expect是基于tcl演变而来的,所以很多语法和tcl类似,基本的语法如下所示:1.1 首行加上/usr/bin/expect1.2 spawn: 后面加上需要执行的shell命令,比如说sp ...

  2. Docker技术入门与实战 第二版-学习笔记-3-Dockerfile 指令详解

    前面已经讲解了FROM.RUN指令,还提及了COPY.ADD,接下来学习其他的指令 5.Dockerfile 指令详解 1> COPY 复制文件 格式: COPY  <源路径> .. ...

  3. Redis学习笔记4-Redis配置详解

    在Redis中直接启动redis-server服务时, 采用的是默认的配置文件.采用redis-server   xxx.conf 这样的方式可以按照指定的配置文件来运行Redis服务.按照本Redi ...

  4. Struts2学习笔记二 配置详解

    Struts2执行流程 1.简单执行流程,如下所示: 在浏览器输入请求地址,首先会被过滤器处理,然后查找主配置文件,然后根据地址栏中输入的/hello去每个package中查找为/hello的name ...

  5. linux命令学习笔记-eval命令详解

    功能说明:重新运算求出参数的内容. 语 法:eval [参数] 补充说明:eval可读取一连串的参数,然后再依参数本身的特性来执行. 参 数:参数不限数目,彼此之间用分号分开. .eval命令将会首先 ...

  6. Struts2学习笔记(二)——配置详解

    1.Struts2配置文件加载顺序: default.properties(默认常量配置) struts-default.xml(默认配置文件,主要配置bean和拦截器) struts-plugin. ...

  7. Android学习笔记之Activity详解

    1 理解Activity Activity就是一个包含应用程序界面的窗口,是Android四大组件之一.一个应用程序可以包含零个或多个Activity.一个Activity的生命周期是指从屏幕上显示那 ...

  8. [C#] 类型学习笔记二:详解对象之间的比较

    继上一篇对象类型后,这里我们一起探讨相等的判定. 相等判断有关的4个方法 CLR中,和相等有关系的方法有这么4种: (1) 最常见的 == 运算符 (2) Object的静态方法ReferenceEq ...

  9. vue.js学习笔记(二)——vue-router详解

    vue-router详解 原文链接:www.jianshu.com 一.前言 要学习vue-router就要先知道这里的路由是什么?为什么我们不能像原来一样直接用<a></a> ...

随机推荐

  1. 卷积层和BN层融合

    常规的神经网络连接结构如下  当网络训练完成, 在推导的时候为了加速运算, 通常将卷积层和 batch-norm 层融合, 原理如下 \[ \begin{align*} y_{conv} & ...

  2. dubbo源码分析11——服务暴露2_doExport()方法分析

    protected synchronized void doExport() { //如果是已经解除暴露的接口则抛出异常 if (unexported) { throw new IllegalStat ...

  3. 内核探测工具systemtap简介【转】

    转自:http://www.cnblogs.com/hazir/p/systemtap_introduction.html systemtap是内核开发者必须要掌握的一个工具,本文我将简单介绍一下此工 ...

  4. python下载夏目友人帳

    python下载夏目友人帐 一般情况下我们使用爬虫更多的应该是爬数据或者图片吧,今天在这里和大家分享一下关于使用爬虫技术来进行视频下载的方法,不仅可以方便的下载一些体积小的视频,针对大容量的视频下载同 ...

  5. Python3学习笔记32-xlwt模块

    xlwt模块是用来写入excel的第三方模块,需要下载安装后才能使用. 设置字体样式 import xlwt #初始化一个excel excel = xlwt.Workbook(encoding='u ...

  6. $Django RESTful规范

    一 什么是RESTful REST与技术无关,代表的是一种软件架构风格,REST是Representational State Transfer的简称,中文翻译为“表征状态转移” REST从资源的角度 ...

  7. CodeVs 1009

    题意: 给出一个整数 n(n<10^30) 和 k 个变换规则(k<=15). 规则: 一位数可变换成另一个一位数: 规则的右部不能为零. 例如:n=234.有规则(k=2): 2-> ...

  8. CentOS 7安装Python3.5

    CentOS 7下安装Python3.5 •安装python3.5可能使用的依赖 yum install openssl-devel bzip2-devel expat-devel gdbm-deve ...

  9. [MySQL]join的细节

    left join,左表返回所有记录,右表只返回跟左表有关联的记录,当右表有N条记录跟左表的某一条记录A关联,那么查询结果会出现N条A记录(相应关联右表的N条记录) right join,右表返回所有 ...

  10. 通过dd命令显示硬盘的读写性能

    测试vdb硬盘的读写速度 1.分区格式化挂载vdb硬盘 2.新建写入文件2 3.测试:文件2中写入数据,设置块大小为100M,拷贝块个数为5 经过测试:测试效果一般count越高越准确,建议为300, ...