C#回顾 –6.特性

1.特性是什么?
Attribute 用来对类、属性、方法等标注额外的信息,贴一个标签(附着物)
通俗:给 类 或 类成员 贴一个标签,就像航空部为你的行李贴一个标签一样
个人理解,特性就是修饰对象元数据的修饰符。

1.是特性 2.是访问修饰符
3.声明修饰符 4.数据类型
5.变量名 6.变量数据值
其中1、2、3、4、5就是元数据,用来描述数据(6)的数据。
2.特性到底是什么?
如上面的 Obsolete ,会不会也是一个如 public 、 static 这样类似的修饰符呢,我们且看看反编译后的中间语言。

意料之外,我们看到了上面的2、3、4、5,而1(特性)怎么跑到里面去了,且是一种看不懂的东东,反正我们知道了不是类似的修饰符。
然后我们接着在vs里面把光标移到 Obsolete 上按F12,如:

原来只是一个继承了 Attrbute 的一个类(class)。那么上面我们看不懂的部分应该就是这个 ObsoleteAttribute 类的实例化了。
我们来回答上面的问题:特性到底是什么?特性只是一个类而已。
3.自定义特性
我们看到上面系统特性 Obsolete 上面还有特性,如: Serializable 、 AttributeUsage 、 Camvisible 等。像这种特性我们称之为“元数据的元数据”(元元数据)。
1.我们分别来解释性上面的三个特性。
Serializable :表示类型支持序列化。
ComVisible :微软定义“控制程序集中个别托管类型、 成员或所有类型对COM的可访问性”。
AttributeUsage :这个比较重要了,基本上每个特性定义都用到了它。它就是用来表示当前这个特性可用于哪些对象。如:类、方法、属性...等等。(只需要用到这个我们就可以自定义特性了)
2.上面有个问题,不知道大家发现没有。
就是我们特性名明明是 Obsolete ,为什么我们F12进去后变成了 ObsoleteAttribute 呢?这其实只是一个微软的约定而已,没有为什么。
其实我们可以两种写法: [ObsoleteAttribute("已过时")] 和 [Obsolete("已过时")] 是等效的,只是我们一般都用后面这种。
3.定义的特性必须继承于 Attribute 。
4.属性没有 set 方法。只能通过构造函数赋值。(这是因为特性语法所致,因为特性的定义只存在单行的中括号中,不能实例化之后在设置属性,所以全部的设置都在后面的小括号里进行的。如果需要有 set 属性,我们就要用到命名参数,下面会继续讲到)
好了,我们通过这四点完全可以自己定义个特性来玩玩了。我们来定义一个给机器看的注释。我们平时的注释都只是给程序员看的,编译之后就全没了。那我们想在代码运行时,弹出我们的注释怎么办,接下来我们用自定义特性来实现,如:
[AttributeUsage(AttributeTargets.All)] //设置可以用于那些对象
public class TMessgAttribute : Attribute
{
public TMessgAttribute() { }
public TMessgAttribute(string createTime, string createCreatename, string mess)
{
this.createTime = createTime;
this.mess = mess;
this.createname = createCreatename;
}
private string createname;
private string mess;
private string createTime;
public string CreateTime
{
get { return createTime; }
}
public string Mess
{
get { return mess; }
}
public string Createname
{
get { return createname; }
}
}
上面是自定义的特性,怎么使用,和系统特性一样,先定义个测试类,
[TMessg("2016-12-15", "tangsansan", "我,我只是测试自定义特性,不要报错哦")]
public class TClass
{
}
我们定义了特性,也使用了特性,然我们却不知道怎么看效果。我们想看到效果怎么办。可以使用反射看看 TClass 类的元数据,如:
System.Reflection.MemberInfo info = typeof(TClass);
/*
* 方法一
* Attribute.GetCustomAttribute 方法 (MemberInfo, Type)
* 检索应用于类型成员的自定义参数。参数指定成员和要搜索自定义成员的类型
* element:一个从 MemberInfo 类派生的对象,该类描述类的构造函数、事件、字段、方法或属性成员。(指定应用了特性的类)。
* attributeType:要搜索的自定义属性的类型或基类型
*/
TMessgAttribute attr = (TMessgAttribute)Attribute.GetCustomAttribute(info, typeof(TMessgAttribute));
Console.WriteLine("类名:{0}", info.Name);
Console.WriteLine("创建时间{0}", attr.CreateTime);
Console.WriteLine("创建人{0}", attr.Createname);
Console.WriteLine("消息{0}", attr.Mess);
Console.WriteLine("-------------");
/*
* 方法二
* MemberInfo.GetCustomAttributes 方法 (Type, Boolean)
* attributeType:要搜索的属性的类型。 仅返回可分配给此类型的属性。
* inherit:true 搜索此成员继承链,以查找这些属性;否则为 false。 属性和事件,则忽略此参数。
*/
object[] attrs = info.GetCustomAttributes(typeof (TMessgAttribute), false);
TMessgAttribute mes = attrs[0] as TMessgAttribute;
Console.WriteLine("创建时间{0}", mes.CreateTime);
Console.WriteLine("创建人{0}", mes.Createname);
Console.WriteLine("消息{0}", mes.Mess);

4.什么是命名参数?
上面的自定义特性都是通过构造函数设置字段私有字段,然后通过只提供了 get 的属性来访问。那么可否直接在特性里面定义拥有 get 和 set 的属性吗?答案是肯定的。那怎么在使用特性的时候设置这个属性呢?我们接着往下看。
我们接着在自定义特性里面添加一个属性。
//修改时间
public string modifyTime{get;set;}
使用自定义特性。
[TMessg("2016-12-15", "tangsansan", "我,我只是测试自定义特性,不要报错哦",modifyTime="2016-11-26")]
public class TClass
{ }
我们发现,直接在输入了构造函数之后接着设置属性就可以。(这就相当于可选参数了,属性当然可以随便你是否设置了。不过这里需要注意了,前面的参数一定要按照定义的特性构造函数的参数顺序)
这种参数,我们称为命名参数。
6.我们来继续要看看AttributeUsage (这个描述特性的特性--“元元数据”)

我们来看看他的这几个属性是干嘛的。从最后一个开始看。
1. AttributeTargets
我们在上面其实就已经看到并也已经使用了。

我们设置的是可用于所有对象。 AttributeTargets 其实是个枚举,每个值对于一个类型对象。
你可以直接在 AttributeTargets F12进去:

我们看到了每个值代表可以用于所对于的对象类型。
2. Inherited (是一个布尔值)
“如果该属性可由派生类和重写成员继承,则为 true ,否则为 false 。 默认值为 true ”
如下,我们设置 Inherited = false 那么继承 TClass 的 T2Class 无法访问到 TClass 中设置的特性元数据。
如果我们想要这样设置怎么办。在 AttributeUsage 中设置 AllowMultiple = true 如:
3. AllowMultiple (也是一个布尔值)
“如果允许指定多个实例,则为 true ;否则为 false 。 默认值为 false 。”
我们设置两个特性试试,如:


反之,我们设置 Inherited = true (或者不设置任何,因为默认就是 true )打印如下:
如果我们想要这样设置怎么办。在 AttributeUsage 中设置 AllowMultiple = true 如:
1.添加一个继承类
public class T2Class : TClass
{
//...........
}
2.更新
[AttributeUsage(AttributeTargets.All , Inherited=false)] //设置可以用于那些对象
public class TMessgAttribute : Attribute
{
//...
}
3.输出


但是要报错,

打印地方的代码需要修改。因为之前是打印一个特性信息,这里是打印一个特性数组集合的信息。
TMessgAttribute[] attrs = (TMessgAttribute[])Attribute.GetCustomAttributes(info, typeof(TMessgAttribute));
foreach (var item in attrs)
{
Console.WriteLine("类名:{0}", info.Name);
Console.WriteLine("创建时间{0}", item.CreateTime);
Console.WriteLine("创建人{0}", item.Createname);
Console.WriteLine("消息{0}", item.Mess);
Console.WriteLine("-------------");
Console.WriteLine("修改时间{0}", item.modifyTime);
}

7.自定义特性可以干什么?
上面我们通过反编译,发现自定义特性实际上就是一个对象调用的最前面加了一段实例化的代码。
那么我们可以做的事可多了,除了像上面一样为对象设置“注释”,我们还可以自定义个特性,给某些方法或是某些类做“操作日志记录”,或者给需要在执行某些方法的时候需要权限,我们可以做个权限认证的特性等等。
这里就需要大家自己去扩展了。
农码一生 《一、特性是什么东东》
http://www.cnblogs.com/zhaopei/p/attribute_is_what.html
C#回顾 –6.特性的更多相关文章
- html+css学习笔记 3[浮动]
inline-block/float(浮动) 回顾:inline-block 特性: 1.块在一排显示 2.内联支持宽高 3.默认内容撑开宽度 4.标签之间的换行间隙被解析(问题) 5.ie ...
- inline-block的升级float:浮动
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...
- TensorRT 3:更快的TensorFlow推理和Volta支持
TensorRT 3:更快的TensorFlow推理和Volta支持 TensorRT 3: Faster TensorFlow Inference and Volta Support 英伟达Tens ...
- [C#] C# 知识回顾 - 特性 Attribute
C# 知识回顾 - 特性 Attribute [博主]反骨仔 [原文地址]http://www.cnblogs.com/liqingwen/p/5911289.html 目录 特性简介 使用特性 特性 ...
- QT5.9 新特性与版本回顾
原文链接: http://blog.qt.io/blog/2017/05/31/qt-5-9-released 翻译内容如下,采用的是第三方某在线翻译软件,所以有些地方不是太精确,纵然大吉做了一定的调 ...
- 第十四章 JDK新特性回顾
14.1.JDK5新特性回顾 自动装箱.拆箱 静态导入 增强for循环 可变参数 枚举 泛型 元数据 14.2.JDK7新特性回顾 对Java集合(Collections)的增强支持 在switch中 ...
- Android Lollipop 5.0 经典新特性回顾
*Tamic 专注移动开发! 更多文章请关注 http://blog.csdn.net/sk719887916 虽然Android已到了7.0 ,但是我们还是不能忘怀视觉革命性改变的5.0,今天回顾下 ...
- Java9发布回顾Java 8的十大新特性
java9已经在北京时间9月22日正式发布,开发者可以在oracle jdk官网上下载到最新的jdk9. 今天,我们先来一起复习一下2014年发布的Java 8的十大新特性.先来喝杯java~~~ 按 ...
- Java知识回顾 (18)Java 8、9、11的新特性
Java 8 Java 8 (又称为 jdk 1.8) 是 Java 语言开发的一个主要版本. Oracle 公司于 2014 年 3 月 18 日发布 Java 8 ,它支持函数式编程,新的 Jav ...
随机推荐
- poj1986 LCA
Distance Queries Time Limit: 2000MS Memory Limit: 30000K Total Submissions: 11759 Accepted: 4157 ...
- C#-WebForm-WebForm开发基础
1.C/S 客户端应用程序 WinForm WPF 平级 数据是存放在其他的电脑上或服务器上 需要从服务器上下载相应的数据,在本地电脑上的客户端里进行加工 数据的加工是在用户的电脑上执行的,会对用户的 ...
- hihoCoder 后缀数组 重复旋律
#1403 : 后缀数组一·重复旋律 时间限制:5000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi平时的一大兴趣爱好就是演奏钢琴.我们知道一个音乐旋律被表示为长度为 N 的数构成 ...
- end2end learning 端到端学习
在DeepLearning的文章中有看到end2end一次,作者们似乎都比较喜欢这个end2end learning的方式.那么到底啥是end2end? 找了一下相关论文,没找到专门讲这个概念的,看来 ...
- 消息中间件:RabbitMQ基本探索
RabbitMQ是一个基于AMQP协议(Advanced Message Queuing Protocol,一个提供统一消息服务的应用层标准高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中 ...
- C#操作剪贴板
操作剪贴版,主要用到了ClipBoard类. 该类位于 System.Windows(WPF)或System.Windows.Forms(Winform)下. 1.设置内容到剪贴版上: 主要用到Cli ...
- Ubuntu学习总结-07 Nodejs和npm的安装
一 安装NodeJS 1 下载nodejs源码 从以下网址下载最新的Nodejs源码 https://nodejs.org/en/download/ 2 安装依赖的 python,gcc,g++ 函数 ...
- API接口:分页
// 查询满足要求的总记录数 $count = M("back")->where($back_map)->count(); $pagecount = ceil($cou ...
- java高级特性
第二章 XML(可扩展标记语言) XML格式能够表达层次结构,并且重复的元素不会被曲解. 与HTML不同,XML是大小写敏感的. 必须有结束符. 属性值必须用引号括起来. 所有属性必须都有属性值. X ...
- Storm 单机版环境搭建
1 需要安装的软件 要使用storm首先要安装以下工具:python.zookeeper.zeromq.jzmq.storm 1.1 安装zeromq wget http://download.zer ...
![]() |
![]() |
![]() |
我们来回答上面的问题:特性到底是什么?特性只是一个类而已。
3.自定义特性
|
|
|
![]() |
4.什么是命名参数?
上面的自定义特性都是通过构造函数设置字段私有字段,然后通过只提供了 get 的属性来访问。那么可否直接在特性里面定义拥有 get 和 set 的属性吗?答案是肯定的。那怎么在使用特性的时候设置这个属性呢?我们接着往下看。
我们接着在自定义特性里面添加一个属性。
//修改时间
public string modifyTime{get;set;}
使用自定义特性。
[TMessg("2016-12-15", "tangsansan", "我,我只是测试自定义特性,不要报错哦",modifyTime="2016-11-26")]
public class TClass
{ }
我们发现,直接在输入了构造函数之后接着设置属性就可以。(这就相当于可选参数了,属性当然可以随便你是否设置了。不过这里需要注意了,前面的参数一定要按照定义的特性构造函数的参数顺序)
这种参数,我们称为命名参数。
6.我们来继续要看看AttributeUsage (这个描述特性的特性--“元元数据”)

我们来看看他的这几个属性是干嘛的。从最后一个开始看。
1. AttributeTargets
我们在上面其实就已经看到并也已经使用了。

我们设置的是可用于所有对象。 AttributeTargets 其实是个枚举,每个值对于一个类型对象。
你可以直接在 AttributeTargets F12进去:

我们看到了每个值代表可以用于所对于的对象类型。
2. Inherited (是一个布尔值)
“如果该属性可由派生类和重写成员继承,则为 true ,否则为 false 。 默认值为 true ”
如下,我们设置 Inherited = false 那么继承 TClass 的 T2Class 无法访问到 TClass 中设置的特性元数据。
如果我们想要这样设置怎么办。在 AttributeUsage 中设置 AllowMultiple = true 如:
3. AllowMultiple (也是一个布尔值)
“如果允许指定多个实例,则为 true ;否则为 false 。 默认值为 false 。”
我们设置两个特性试试,如:


反之,我们设置 Inherited = true (或者不设置任何,因为默认就是 true )打印如下:
如果我们想要这样设置怎么办。在 AttributeUsage 中设置 AllowMultiple = true 如:
1.添加一个继承类
public class T2Class : TClass
{
//...........
}
2.更新
[AttributeUsage(AttributeTargets.All , Inherited=false)] //设置可以用于那些对象
public class TMessgAttribute : Attribute
{
//...
}
3.输出


但是要报错,

打印地方的代码需要修改。因为之前是打印一个特性信息,这里是打印一个特性数组集合的信息。
TMessgAttribute[] attrs = (TMessgAttribute[])Attribute.GetCustomAttributes(info, typeof(TMessgAttribute));
foreach (var item in attrs)
{
Console.WriteLine("类名:{0}", info.Name);
Console.WriteLine("创建时间{0}", item.CreateTime);
Console.WriteLine("创建人{0}", item.Createname);
Console.WriteLine("消息{0}", item.Mess);
Console.WriteLine("-------------");
Console.WriteLine("修改时间{0}", item.modifyTime);
}

7.自定义特性可以干什么?
上面我们通过反编译,发现自定义特性实际上就是一个对象调用的最前面加了一段实例化的代码。
那么我们可以做的事可多了,除了像上面一样为对象设置“注释”,我们还可以自定义个特性,给某些方法或是某些类做“操作日志记录”,或者给需要在执行某些方法的时候需要权限,我们可以做个权限认证的特性等等。
这里就需要大家自己去扩展了。
农码一生 《一、特性是什么东东》
http://www.cnblogs.com/zhaopei/p/attribute_is_what.html
|
|
我们发现,直接在输入了构造函数之后接着设置属性就可以。(这就相当于可选参数了,属性当然可以随便你是否设置了。不过这里需要注意了,前面的参数一定要按照定义的特性构造函数的参数顺序)
这种参数,我们称为命名参数。
6.我们来继续要看看AttributeUsage (这个描述特性的特性--“元元数据”)
![]() |
1. AttributeTargets
我们在上面其实就已经看到并也已经使用了。
![]() |
![]() |
如果我们想要这样设置怎么办。在 AttributeUsage 中设置 AllowMultiple = true 如:
![]() |

反之,我们设置 Inherited = true (或者不设置任何,因为默认就是 true )打印如下:
如果我们想要这样设置怎么办。在 AttributeUsage 中设置 AllowMultiple = true 如:
1.添加一个继承类
2.更新
3.输出 |
![]() |
但是要报错,
![]() |
打印地方的代码需要修改。因为之前是打印一个特性信息,这里是打印一个特性数组集合的信息。
|

7.自定义特性可以干什么?
上面我们通过反编译,发现自定义特性实际上就是一个对象调用的最前面加了一段实例化的代码。
那么我们可以做的事可多了,除了像上面一样为对象设置“注释”,我们还可以自定义个特性,给某些方法或是某些类做“操作日志记录”,或者给需要在执行某些方法的时候需要权限,我们可以做个权限认证的特性等等。
这里就需要大家自己去扩展了。

农码一生 《一、特性是什么东东》
http://www.cnblogs.com/zhaopei/p/attribute_is_what.html
C#回顾 –6.特性的更多相关文章
- html+css学习笔记 3[浮动]
inline-block/float(浮动) 回顾:inline-block 特性: 1.块在一排显示 2.内联支持宽高 3.默认内容撑开宽度 4.标签之间的换行间隙被解析(问题) 5.ie ...
- inline-block的升级float:浮动
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...
- TensorRT 3:更快的TensorFlow推理和Volta支持
TensorRT 3:更快的TensorFlow推理和Volta支持 TensorRT 3: Faster TensorFlow Inference and Volta Support 英伟达Tens ...
- [C#] C# 知识回顾 - 特性 Attribute
C# 知识回顾 - 特性 Attribute [博主]反骨仔 [原文地址]http://www.cnblogs.com/liqingwen/p/5911289.html 目录 特性简介 使用特性 特性 ...
- QT5.9 新特性与版本回顾
原文链接: http://blog.qt.io/blog/2017/05/31/qt-5-9-released 翻译内容如下,采用的是第三方某在线翻译软件,所以有些地方不是太精确,纵然大吉做了一定的调 ...
- 第十四章 JDK新特性回顾
14.1.JDK5新特性回顾 自动装箱.拆箱 静态导入 增强for循环 可变参数 枚举 泛型 元数据 14.2.JDK7新特性回顾 对Java集合(Collections)的增强支持 在switch中 ...
- Android Lollipop 5.0 经典新特性回顾
*Tamic 专注移动开发! 更多文章请关注 http://blog.csdn.net/sk719887916 虽然Android已到了7.0 ,但是我们还是不能忘怀视觉革命性改变的5.0,今天回顾下 ...
- Java9发布回顾Java 8的十大新特性
java9已经在北京时间9月22日正式发布,开发者可以在oracle jdk官网上下载到最新的jdk9. 今天,我们先来一起复习一下2014年发布的Java 8的十大新特性.先来喝杯java~~~ 按 ...
- Java知识回顾 (18)Java 8、9、11的新特性
Java 8 Java 8 (又称为 jdk 1.8) 是 Java 语言开发的一个主要版本. Oracle 公司于 2014 年 3 月 18 日发布 Java 8 ,它支持函数式编程,新的 Jav ...
随机推荐
- poj1986 LCA
Distance Queries Time Limit: 2000MS Memory Limit: 30000K Total Submissions: 11759 Accepted: 4157 ...
- C#-WebForm-WebForm开发基础
1.C/S 客户端应用程序 WinForm WPF 平级 数据是存放在其他的电脑上或服务器上 需要从服务器上下载相应的数据,在本地电脑上的客户端里进行加工 数据的加工是在用户的电脑上执行的,会对用户的 ...
- hihoCoder 后缀数组 重复旋律
#1403 : 后缀数组一·重复旋律 时间限制:5000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi平时的一大兴趣爱好就是演奏钢琴.我们知道一个音乐旋律被表示为长度为 N 的数构成 ...
- end2end learning 端到端学习
在DeepLearning的文章中有看到end2end一次,作者们似乎都比较喜欢这个end2end learning的方式.那么到底啥是end2end? 找了一下相关论文,没找到专门讲这个概念的,看来 ...
- 消息中间件:RabbitMQ基本探索
RabbitMQ是一个基于AMQP协议(Advanced Message Queuing Protocol,一个提供统一消息服务的应用层标准高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中 ...
- C#操作剪贴板
操作剪贴版,主要用到了ClipBoard类. 该类位于 System.Windows(WPF)或System.Windows.Forms(Winform)下. 1.设置内容到剪贴版上: 主要用到Cli ...
- Ubuntu学习总结-07 Nodejs和npm的安装
一 安装NodeJS 1 下载nodejs源码 从以下网址下载最新的Nodejs源码 https://nodejs.org/en/download/ 2 安装依赖的 python,gcc,g++ 函数 ...
- API接口:分页
// 查询满足要求的总记录数 $count = M("back")->where($back_map)->count(); $pagecount = ceil($cou ...
- java高级特性
第二章 XML(可扩展标记语言) XML格式能够表达层次结构,并且重复的元素不会被曲解. 与HTML不同,XML是大小写敏感的. 必须有结束符. 属性值必须用引号括起来. 所有属性必须都有属性值. X ...
- Storm 单机版环境搭建
1 需要安装的软件 要使用storm首先要安装以下工具:python.zookeeper.zeromq.jzmq.storm 1.1 安装zeromq wget http://download.zer ...