学会给你的类(及成员)来定制一套自己的Attribute吧
在通过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吧的更多相关文章
- C++点滴----关于类常成员函数
关于C++中,类的常成员函数 声明样式为: 返回类型 <类标识符::>函数名称(参数表) const 一些说明: 1.const是函数声明的一部分,在函数的实现部分也需要加上const ...
- c++函数模板作为类的成员函数,编译报错LNK2019的解决方法
为了使某个类的成员函数能对不同的参数进行相同的处理,需要用到函数模板,即template<typename T> void Function(). 编译时报错LNK2019 解决方法: 1 ...
- fielderror里的fieldName代表的是jsp里的fieldName还是Action类的成员变量?(待解答)
1.值栈的Action对象中会有一个fielderror属性,代表着字段错误. fielderror是Map<String,List<String>>类型 例如下面的值栈里可看 ...
- [.net 面向对象编程基础] (10) 类的成员(字段、属性、方法)
[.net 面向对象编程基础] (10) 类的成员(字段.属性.方法) 前面定义的Person的类,里面的成员包括:字段.属性.方法.事件等,此外,前面说的嵌套类也是类的成员. a.类的成员为分:静态 ...
- 深入理解PHP内核(十四)类的成员变量及方法
原文链接:http://www.orlion.ga/1237/ 类的成员变量在PHP中本质是一个变量,只是这些变量都归属于某个类,并且给这些变量是有访问控制的. 类的成员方法在PHP中本质是一个函数, ...
- [javaSE] 反射-获取类的成员属性和构造方法
成员属性和构造方法皆为对象,通过Class对象的方法可以得到 package com.tsh.reflect; import java.lang.reflect.Constructor; import ...
- [转载]能不能同时用static和const修饰类的成员函数?
题目(一):我们可以用static修饰一个类的成员函数,也可以用const修饰类的成员函数(写在函数的最后表示不能修改成员变量,不是指写在前面表示返回值为常量).请问:能不能同时用static和con ...
- 回调函数中使用MFC类的成员或对话框控件的简单方法
在MFC的很多程序中,常常需要在回调函数中调用MFC类的类成员变量.类成员函数,亦或者对话框控件的句柄.由于回调函数是基于C编程的Windows SDK的技术,而类成员又有this指针客观条件限制.. ...
- Python全栈--9.1--面向对象进阶-super 类对象成员--类属性- 私有属性 查找源码类对象步骤 类特殊成员 isinstance issubclass 异常处理
上一篇文章介绍了面向对象基本知识: 面向对象是一种编程方式,此编程方式的实现是基于对 类 和 对象 的使用 类 是一个模板,模板中包装了多个“函数”供使用(可以讲多函数中公用的变量封装到对象中) 对象 ...
随机推荐
- Configure a VLAN on top of a team with NetworkManager (nmcli) in RHEL7
SOLUTION VERIFIED September 13 2016 KB1248793 Environment Red Hat Enterprise Linux 7 NetworkManager ...
- python enumerate 用法
A new built-in function, enumerate() , will make certain loops a bit clearer. enumerate(thing) , whe ...
- JVM类加载
JVM的类加载机制就是:JVM把描述类的class文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被JVM直接使用的Java类型 ClassLoader JVM中的ClassLoade ...
- Win10提示没有权限使用网络资源问题解决
借鉴链接:http://www.cr173.com/html/67361_1.html Win10提示没有权限使用网络资源解决方法 1.打开控制面板; 2.在所有控制面板项中找到凭据管理器; 3.添加 ...
- 嵌入式C语言代码的调试技巧
在项目开发的过程中,不可避免的会遇到调试代码的情况. 刚开始写代码时,我们想看具体执行到哪儿时,往往这么写: printf("***** Code is here! *****\n" ...
- [转] 从知名外企到创业公司做CTO是一种怎样的体验?
这是我近期接受51CTO记者李玲玲采访的一篇文章,分享给大家. 作者:李玲玲来源:51cto.com|2016-12-30 15:47 http://cio.51cto.com/art/201612/ ...
- [转]ThinkPHP中实例化对象M()和D()的区别,select和find的区别
1.ThinkPHP中实例化对象M()和D()的区别 在实例化的过程中,经常使用D方法和M方法,这两个方法的区别在于M方法实例化模型无需用户为每个数据表定义模型类,如果D方法没有找到定义的模型类,则会 ...
- 我的MYSQL学习心得(九) 索引
我的MYSQL学习心得(九) 索引 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据类 ...
- 一步步开发自己的博客 .NET版(9、从model first替换成code first 问题记录)
为什么要改用code first 用过code first的基本上都不会再想用回model first或是db first(谁用谁知道).不要问我为什么不一开始就直接使用code first,因为那个 ...
- keepalived 知识备注
keepalived可用于配置nginx/lvs等负载均衡设备的双机热备. keepalived基于VRRP协议,简单的说就是两个物理路由节点(一主一备),虚拟成一个逻辑上的路由节点. 实际消息的路由 ...