在通过Visual Studio创建的C#程序集中,都包含了一个AssemblyInfo.cs的文件,在这个文件中,我们常常会看到这样的代码

[assembly: AssemblyTitle("AttributeTutorial")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("AttributeTutorial")]
[assembly: AssemblyCopyright("Copyright ©  2016")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

从这些代码及他们的注释中,我们大概知道他们是用来描述程序集的相关信息,那么是不是我们平常写的代码中的类、类成员是不是也有这样的附加信息呢?答案是肯定的。比如最常见的位枚举、调用另一种语言开发的dll...

    [Flags]
    enum Actions
    {
        None = 0,
        Read = 0x01,
        Write = 0x02,
        ReadWrite = Read | Write,
        Delete = 0x04
    }
  [DllImport("user32.dll")]
  public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

定制自己的Attribute

定制自己的Attribute类,首先要继承System.Attribute,并用Attribute作为后缀。下面的例子中的DescriptionAttribute其实在System.ComponentModel下已近有实现,这里我们只是作为一个自己的简单的例子

    //AttributeUsage的第一个参数,告诉编译器这个特性应用的范围,第二个参数指的是派生类及重写成员是否也继承该特性,第三个参数表示是否可以为类型或成员指定多个特性
    [System.AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = true)]
    sealed class DescriptionAttribute : Attribute
    {
        // See the attribute guidelines at
        //  http://go.microsoft.com/fwlink/?LinkId=85236
        readonly string description;

        // This is a positional argument
        public DescriptionAttribute(string description)
        {
            this.description = description;

            // TODO: Implement code here
        }

        public string Description
        {
            get { return description; }
        }

        // This is a named argument
        public int NamedInt { get; set; }
    }

下面我们就用刚才自定义的特性,来简单的完成一些事情,首先我们像下面那样把刚才的枚举类型加上我们定义的特性

    [Flags]
    [Description("文件的访问")]
    enum Actions
    {
        None = 0,
        Read = 0x01,
        Write = 0x02,
        ReadWrite = Read | Write,
        Delete = 0x04
    }

那么加上这个特性有什么用呢?怎么体现他的作用呢?不要着急,我们这就来实现

    [Description("主程序")]
    class Program
    {
        static void Main(string[] args)
        {
            ClassDescriptionDisplay(typeof(Actions));
            ClassDescriptionDisplay(typeof(Program));
            Console.ReadKey();
        }

        static void ClassDescriptionDisplay(Type type)
        {
            if (type.IsDefined(typeof(DescriptionAttribute), false))//检测类型是否包含此特性
            {
                DescriptionAttribute attrs = (DescriptionAttribute)type.GetCustomAttributes(typeof(DescriptionAttribute), false)[0];//获取特性
                Console.WriteLine("{0}:{1}",type.Name,attrs.Description);
            }
            else
            {
                //另外的处理
            }
        }
    }

通过上面的代码,现在我们知道,我们可以为类及他的成员添加好配置,然后在程序运行的过程中根据配置动态的去处理一些问题。其实这个也就是特性的最大功能。

应用

特性的应用范围很广,比如我们可以为实体类的各个属性添加一个特性,这样的话在保存数据的时候不用再一个个的去写属性的判断,比如序列化的时候,只想序列化部分字段,但是要完成这些功能,还需要进一步学习反射的相关知识,这一篇我们的重点是在定制特性

    public class RegisterViewModel
    {
        [Required]
        [EmailAddress]
        [Display(Name = "电子邮件")]
        public string Email { get; set; }

        [Required]
        [StringLength(100, ErrorMessage = "{0} 必须至少包含 {2} 个字符。", MinimumLength = 6)]
        [DataType(DataType.Password)]
        [Display(Name = "密码")]
        public string Password { get; set; }

        [DataType(DataType.Password)]
        [Display(Name = "确认密码")]
        [Compare("Password", ErrorMessage = "密码和确认密码不匹配。")]
        public string ConfirmPassword { get; set; }
    }

学会给你的类(及成员)来定制一套自己的Attribute吧的更多相关文章

  1. C++点滴----关于类常成员函数

    关于C++中,类的常成员函数 声明样式为:   返回类型 <类标识符::>函数名称(参数表) const 一些说明: 1.const是函数声明的一部分,在函数的实现部分也需要加上const ...

  2. c++函数模板作为类的成员函数,编译报错LNK2019的解决方法

    为了使某个类的成员函数能对不同的参数进行相同的处理,需要用到函数模板,即template<typename T> void Function(). 编译时报错LNK2019 解决方法: 1 ...

  3. fielderror里的fieldName代表的是jsp里的fieldName还是Action类的成员变量?(待解答)

    1.值栈的Action对象中会有一个fielderror属性,代表着字段错误. fielderror是Map<String,List<String>>类型 例如下面的值栈里可看 ...

  4. [.net 面向对象编程基础] (10) 类的成员(字段、属性、方法)

    [.net 面向对象编程基础] (10) 类的成员(字段.属性.方法) 前面定义的Person的类,里面的成员包括:字段.属性.方法.事件等,此外,前面说的嵌套类也是类的成员. a.类的成员为分:静态 ...

  5. 深入理解PHP内核(十四)类的成员变量及方法

    原文链接:http://www.orlion.ga/1237/ 类的成员变量在PHP中本质是一个变量,只是这些变量都归属于某个类,并且给这些变量是有访问控制的. 类的成员方法在PHP中本质是一个函数, ...

  6. [javaSE] 反射-获取类的成员属性和构造方法

    成员属性和构造方法皆为对象,通过Class对象的方法可以得到 package com.tsh.reflect; import java.lang.reflect.Constructor; import ...

  7. [转载]能不能同时用static和const修饰类的成员函数?

    题目(一):我们可以用static修饰一个类的成员函数,也可以用const修饰类的成员函数(写在函数的最后表示不能修改成员变量,不是指写在前面表示返回值为常量).请问:能不能同时用static和con ...

  8. 回调函数中使用MFC类的成员或对话框控件的简单方法

    在MFC的很多程序中,常常需要在回调函数中调用MFC类的类成员变量.类成员函数,亦或者对话框控件的句柄.由于回调函数是基于C编程的Windows SDK的技术,而类成员又有this指针客观条件限制.. ...

  9. Python全栈--9.1--面向对象进阶-super 类对象成员--类属性- 私有属性 查找源码类对象步骤 类特殊成员 isinstance issubclass 异常处理

    上一篇文章介绍了面向对象基本知识: 面向对象是一种编程方式,此编程方式的实现是基于对 类 和 对象 的使用 类 是一个模板,模板中包装了多个“函数”供使用(可以讲多函数中公用的变量封装到对象中) 对象 ...

随机推荐

  1. PHP之时间和日期函数

    // 时间日期函数 Time <?php date_default_timezone_set('UTC'); // 获取当前时间的时间戳 $time0 = mktime(); $time1 = ...

  2. 模仿Linux内核kfifo实现的循环缓存

    想实现个循环缓冲区(Circular Buffer),搜了些资料多数是基于循环队列的实现方式.使用一个变量存放缓冲区中的数据长度或者空出来一个空间来判断缓冲区是否满了.偶然间看到分析Linux内核的循 ...

  3. Cesium简介以及离线部署运行

    Cesium简介 cesium是国外一个基于JavaScript编写的使用WebGL的地图引擎,一款开源3DGIS的js库.cesium支持3D,2D,2.5D形式的地图展示,可以自行绘制图形,高亮区 ...

  4. TabLayout + ViewPager

    一.实现思路 1.在build.gradle中添加依赖,例如: compile 'com.android.support:support-v4:23.4.0'compile 'com.android. ...

  5. DB2重启数据库实例

    DB2重启数据库实例时,有时停止实例会失败,此时需要先确认没有应用链接数据库,然后再关闭数据库实例,并重新启动. 1.查看是否有活动的链接 命令:db2 list applications for d ...

  6. MySQL+Amoeba实现数据库主从复制和读写分离

    MySQL读写分离是在主从复制的基础上进一步通过在master上执行写操作,在slave上执行读操作来实现的.通过主从复制,master上的数据改动能够同步到slave上,从而保持了数据的一致性.实现 ...

  7. jsp富文本图片和数据上传

    好记性不如烂笔头,记录一下. 2016的最后一天,以一篇博客结尾迎接新的一年. 此处用的富文本编辑器是wangEditor,一款开源的轻量级的富文本编辑器,这里着重说一下里面的图片上传功能. 服务器端 ...

  8. centos7+mono4.2.3.4+jexus5.8.1跨平台起飞

    很早之前就开始关注.net跨平台,最近正好测试了下用EF6连接mysql,于是就想直接把网站扔进Linux.查了很多资料,鼓捣了两个晚上,终于成功. 这里我使用的是budgetvm的1G openvz ...

  9. 【腾讯Bugly干货分享】OCS——史上最疯狂的iOS动态化方案

    本文来自于腾讯Bugly公众号(weixinBugly),未经作者同意,请勿转载,原文地址:https://mp.weixin.qq.com/s/zctwM2Wf8c6_sxT_0yZvXg 导语 在 ...

  10. 利用Netty构建自定义协议的通信

    在复杂的网络世界中,各种应用之间通信需要依赖各种各样的协议,比如:HTTP,Telnet,FTP,SMTP等等. 在开发过程中,有时候我们需要构建一些适应自己业务的应用层协议,Netty作为一个非常优 ...