.NET基础 (18)特性
特性
1 什么是特性,如何自定义一个特性
2 .NET中特性可以在哪些元素上使用
3 有哪几种方法可以获知一个元素是否申明某个特性
4 一个元素是否可以重复申明同一个特性
特性
1 什么是特性,如何自定义一个特性
特性是一种特殊的用以申明式编程的机制,特性类型是一族继承自System.Attribute的类型,在编译时,特性的使用会被写入元数据中,以共运行或者程序中的反射使用。自定义一个特性,本质上是定义一个继承自System.Attribute的类型。
自定义特性示例:
/// <summary>
/// 自定义的特性
/// </summary>
[AttributeUsage(AttributeTargets.Class)]
public class MyAttribute : Attribute
{
private String _classname;
public MyAttribute(String s)
{
_classname = s;
}
//一个只读属性
public String ClassName
{
get
{
return _classname;
}
}
} /// <summary>
/// 使用自定义属性
/// </summary>
[MyAttribute("UseMyAttribute")]
class UseMyAttribute
{
static void Main(string[] args)
{
Type t = typeof(UseMyAttribute);
Object[] attributes = t.GetCustomAttributes(false);
MyAttribute att = (MyAttribute)attributes[];
Console.WriteLine(att.ClassName);
Console.Read();
}
}
输出:
UseMyAttribute
特性将被写入元数据中,所以特性的使用基本都基于反射机制。
有几点需要注意:
- 按照惯例,特性的名字都以Attribute结尾。
- C#中,为了使用方便,可以省略特性名字后缀Attribute,如 [MyAttribute("UseMyAttribute")] 可写为 [My("UseMyAttribute")]。
- 特性自身可以添加其他特性。
2 .NET中特性可以在哪些元素上使用
特性可以应用在程序集、模块、结构、枚举、构造方法、方法、属性、字段、事件、接口、参数、委托、返回参数和泛型参数这些目标元素上。通过AttributeUsage特性可以限制自定义特性的使用范围。
示例:
using System; //应用在程序集上
[assembly: MyAttribute]
//应用在模块上
[module: MyAttribute] //应用在类型上
[type: MyAttribute]
class AttributeTargets<[typevar: MyAttribute] T> //泛型参数上
{
//应用在字段上
[field: MyAttribute]
private String _MyString; //应用在构造方法上
[method: MyAttribute]
public AttributeTargets()
{
} //应用在属性上
[property: MyAttribute]
public String MyString
{
get
{
return _MyString;
}
} //应用在方法上
[return: MyAttribute]
public String Format(
//应用在方法参数上
[param: MyAttribute]String f)
{
return null;
} //应用在事件上
[event: MyAttribute]
public event EventHandler MyEvent;
} /// <summary>
/// 一个空的特性
/// 可用于所有元素
/// </summary>
public class MyAttribute : System.Attribute
{
} public class MainClass
{
static void Main(string[] args)
{
}
}
3 有哪几种方法可以获知一个元素是否申明某个特性
System.Attribute.IsDefined
System.Attribute.GetCustomAttribute
System.Attribute.GetCustomAttributes
System.Reflection.CustomAttributeData
示例:
[My("GetAttributes")]
class GetAttributes
{
static void Main(string[] args)
{
Type attributeType = typeof(MyAttribute);
Type thisClass = typeof(GetAttributes); //使用IsDefined方法
bool defined = Attribute.IsDefined(
thisClass,
attributeType);
Console.WriteLine(
"GetAttributes类型是否申明了MyAttribute特性:{0}",
defined.ToString()); //使用Attribute.GetCustomAttribute方法
Attribute att = Attribute.GetCustomAttribute(
thisClass,
attributeType);
if (att != null)
{
Console.WriteLine(
"GetAttributes类型申明了MyAttribute特性。");
Console.WriteLine("名字为:{0}",
((MyAttribute)att).Name);
} //使用Attribute.GetCustomAttributes方法
Attribute[] atts = Attribute.GetCustomAttributes(
thisClass,
attributeType);
if (atts.Length > )
{
Console.WriteLine(
"GetAttributes类型申明了MyAttribute特性。");
Console.WriteLine("名字为:{0}",
((MyAttribute)atts[]).Name);
} //使用System.Reflection.CustomAttributeData类型
IList<CustomAttributeData> list =
CustomAttributeData.GetCustomAttributes(thisClass);
if (list.Count > )
{
Console.WriteLine(
"GetAttributes类型申明了MyAttribute特性。");
//注意这里可以对特性进行分析,但不能得到其实例
CustomAttributeData attdata = list[];
Console.WriteLine("特性的名字是:{0}",
attdata.Constructor.DeclaringType.Name);
Console.WriteLine("特性的构造方法有{0}个参数。",
attdata.ConstructorArguments.Count);
}
Console.Read();
}
} /// <summary>
/// 一个简单的特性
/// </summary>
[AttributeUsage(AttributeTargets.All)]
public sealed class MyAttribute : Attribute
{
private String _name;
public MyAttribute(String s)
{
_name = s;
}
public String Name
{
get
{
return _name;
}
}
}
输出:
GetAttributes类型是否申明了MyAttribute特性:True
GetAttributes类型申明了MyAttribute特性。
名字为:GetAttributes
GetAttributes类型申明了MyAttribute特性。
名字为:GetAttributes
GetAttributes类型申明了MyAttribute特性。
特性的名字是:MyAttribute
特性的构造方法有1个参数。
4 一个元素是否可以重复申明同一个特性
当一个特性申明了AttributeUsage特性并且显示地将AllowMultiple属性设置为true时,该特性就可以在同一元素上多次申明,否则的话编译器将被报错。
示例:
[My("Class1")]
[My("Class2")]
[My("Class1")]
class AllowMultiple
{
static void Main(string[] args)
{
}
} /// <summary>
/// 使用AttributeUsage限定使用范围
/// 并且允许在同一元素上多次申明
/// </summary>
[AttributeUsage(AttributeTargets.Class,AllowMultiple=true)]
class MyAttribute : Attribute
{
private String _s; public MyAttribute(String s)
{
_s = s;
}
}
转载请注明出处:
作者:JesseLZJ
出处:http://jesselzj.cnblogs.com
.NET基础 (18)特性的更多相关文章
- [.net 面向对象编程基础] (18) 泛型
[.net 面向对象编程基础] (18) 泛型 上一节我们说到了两种数据类型数组和集合,数组是指包含同一类型的多个元素,集合是指.net中提供数据存储和检索的专用类. 数组使用前需要先指定大小,并且检 ...
- 十八. Python基础(18)常用模块
十八. Python基础(18)常用模块 1 ● 常用模块及其用途 collections模块: 一些扩展的数据类型→Counter, deque, defaultdict, namedtuple, ...
- day31 Pyhton 面向对象的基础 三大特性
一.内容回顾 封装 1.概念 笔记 2.__名字 在类的外部就不能用了 3.私有化的 不能被子类继承,也不能在其他任何类中调用 三个装饰器方法(装饰类中的方法) 1.不被修饰的 普通方法,会使用对象 ...
- C# 基础知识-特性
C基础 - 特性 一.特性 1>特性本质就是一个类,直接或者间接的继承了Attribute 2>特性就是在不破话类封装的前提下,加点额外的信息或者行为 特性添加后,编译会在元素内部产生IL ...
- python基础——18(面向对象2+异常处理)
一.组合 自定义类的对象作为另一个类的属性. class Teacher: def __init__(self,name,age): self.name = name self.age = age t ...
- HTTP 基础(特性、请求方法、状态码、字段)
1. HTTP 简介(含义.特性.缺点) 2. HTTP 报文 3. GET 和 POST 4. 状态码 5. HTTP 头字段 1. HTTP 简介 HTTP 的含义 HTTP (HyperText ...
- 【C#进阶系列】18 特性Attribute
这个东西有的叫定制特性,然而我喜欢直接叫特性,但是这样的话一些人不知道我说的是什么,如果我说是Attribute的话那么知道的或者用过的就都懂了. 还记得讲到枚举和位标志那一章,关于位标志,有一个[F ...
- OC基础(18)
Category基本概念 Category注意事项 *:first-child { margin-top: 0 !important; } body > *:last-child { margi ...
- python3.3 基础 新特性
前段时间看到对 python 之父的采访,持 python应尽量使用新版的态度. 所以学习,就从比较新的版本开始吧. 3.x 之后的版本与2.x 的版本还是有些不同,仅从入门的基础部分即可感受到, 比 ...
- Python基础——3特性
特性 切片 L=[0,1,2,3,4,5,6,7,8,9,10] L[:3]=[0,1,2] L[-2:]=[9,10] L[1:3]=[1,2] L[::3]=[0,3,6,9] L[:5:2]=[ ...
随机推荐
- 转- 集群NAS技术架构
集群NAS技术架构 标签: 集群存储负载均衡扩展服务器网络 原贴:http://blog.csdn.net/liuaigui/article/details/6422700 作者刘爱贵 1 什么是集群 ...
- JS 奇淫巧技 转
1. 在 String.prototype.replace 方法中使用 /g 和 /i 标志位 令很多 JavaScript 初学者意外的是,字符串的 replace 方法并不会 替换所有匹配的子串— ...
- RDLC报表系列一
1.报表项目搭建: 配置好后,单击Web服务URL:http://lg-20151517ryre/ReportServer 如果电脑系统打开的时候没有设置密码的话,此时打开有可能会出现需要登录名和密码 ...
- HDU 1686 Oulipo(优化的KMP)
Oulipo Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Subm ...
- CSS布局模型学习
转自:http://www.cnblogs.com/erliang/p/4092192.html CSS布局模型学习 参考链接慕课网:HTML+CSS基础课程 知识基础 1. 样式 内联 嵌入 外 ...
- 关于Android App开发知识体系的一个小总结
前言 本文从热更新.异步并发.性能优化.网络请求等多个方面对Android App开发的知识体系进行了一个分类总结.欢迎大家沟通交流. 热更新 [原]热更新开源项目Tinker源码解析之Dex热更新 ...
- 修改jvm xms参数
http://hi.baidu.com/200770842223/item/9358aad4f3194e1a20e2501b http://www.cnblogs.com/mingforyou/arc ...
- Phython智能分词开发
Git/GitHub 一.开发环境安装 1.安装Anaconda 官方下载地址:https://www.anaconda.com/download/ Anaconda自带Flask 2.安装模块/插件 ...
- 常见反编译产生错误 k__BackingField 解决办法
常见反编译产生错误 k__BackingField 解决办法 无聊反编译小蚂蚁出现上千的错同样的错 private bool <EnableRuntimeHandler> ...
- 2 数据库开发--MySQL下载(windows)
Windows:(mysql) 操作: 0.下载安装mysql www.mysql.org downloads->进入社区community community 5.7.21 下载5.6 Mic ...