特性
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)特性的更多相关文章

  1. [.net 面向对象编程基础] (18) 泛型

    [.net 面向对象编程基础] (18) 泛型 上一节我们说到了两种数据类型数组和集合,数组是指包含同一类型的多个元素,集合是指.net中提供数据存储和检索的专用类. 数组使用前需要先指定大小,并且检 ...

  2. 十八. Python基础(18)常用模块

    十八. Python基础(18)常用模块 1 ● 常用模块及其用途 collections模块: 一些扩展的数据类型→Counter, deque, defaultdict, namedtuple, ...

  3. day31 Pyhton 面向对象的基础 三大特性

    一.内容回顾 封装 1.概念 笔记 2.__名字 在类的外部就不能用了 3.私有化的 不能被子类继承,也不能在其他任何类中调用 三个装饰器方法(装饰类中的方法) 1.不被修饰的  普通方法,会使用对象 ...

  4. C# 基础知识-特性

    C基础 - 特性 一.特性 1>特性本质就是一个类,直接或者间接的继承了Attribute 2>特性就是在不破话类封装的前提下,加点额外的信息或者行为 特性添加后,编译会在元素内部产生IL ...

  5. python基础——18(面向对象2+异常处理)

    一.组合 自定义类的对象作为另一个类的属性. class Teacher: def __init__(self,name,age): self.name = name self.age = age t ...

  6. HTTP 基础(特性、请求方法、状态码、字段)

    1. HTTP 简介(含义.特性.缺点) 2. HTTP 报文 3. GET 和 POST 4. 状态码 5. HTTP 头字段 1. HTTP 简介 HTTP 的含义 HTTP (HyperText ...

  7. 【C#进阶系列】18 特性Attribute

    这个东西有的叫定制特性,然而我喜欢直接叫特性,但是这样的话一些人不知道我说的是什么,如果我说是Attribute的话那么知道的或者用过的就都懂了. 还记得讲到枚举和位标志那一章,关于位标志,有一个[F ...

  8. OC基础(18)

    Category基本概念 Category注意事项 *:first-child { margin-top: 0 !important; } body > *:last-child { margi ...

  9. python3.3 基础 新特性

    前段时间看到对 python 之父的采访,持 python应尽量使用新版的态度. 所以学习,就从比较新的版本开始吧. 3.x 之后的版本与2.x 的版本还是有些不同,仅从入门的基础部分即可感受到, 比 ...

  10. 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]=[ ...

随机推荐

  1. 转- 集群NAS技术架构

    集群NAS技术架构 标签: 集群存储负载均衡扩展服务器网络 原贴:http://blog.csdn.net/liuaigui/article/details/6422700 作者刘爱贵 1 什么是集群 ...

  2. JS 奇淫巧技 转

    1. 在 String.prototype.replace 方法中使用 /g 和 /i 标志位 令很多 JavaScript 初学者意外的是,字符串的 replace 方法并不会 替换所有匹配的子串— ...

  3. RDLC报表系列一

    1.报表项目搭建: 配置好后,单击Web服务URL:http://lg-20151517ryre/ReportServer 如果电脑系统打开的时候没有设置密码的话,此时打开有可能会出现需要登录名和密码 ...

  4. HDU 1686 Oulipo(优化的KMP)

    Oulipo Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Subm ...

  5. CSS布局模型学习

    转自:http://www.cnblogs.com/erliang/p/4092192.html CSS布局模型学习   参考链接慕课网:HTML+CSS基础课程 知识基础 1. 样式 内联 嵌入 外 ...

  6. 关于Android App开发知识体系的一个小总结

     前言 本文从热更新.异步并发.性能优化.网络请求等多个方面对Android App开发的知识体系进行了一个分类总结.欢迎大家沟通交流. 热更新 [原]热更新开源项目Tinker源码解析之Dex热更新 ...

  7. 修改jvm xms参数

    http://hi.baidu.com/200770842223/item/9358aad4f3194e1a20e2501b http://www.cnblogs.com/mingforyou/arc ...

  8. Phython智能分词开发

    Git/GitHub 一.开发环境安装 1.安装Anaconda 官方下载地址:https://www.anaconda.com/download/ Anaconda自带Flask 2.安装模块/插件 ...

  9. 常见反编译产生错误 k__BackingField 解决办法

    常见反编译产生错误 k__BackingField 解决办法     无聊反编译小蚂蚁出现上千的错同样的错       private bool <EnableRuntimeHandler> ...

  10. 2 数据库开发--MySQL下载(windows)

    Windows:(mysql) 操作: 0.下载安装mysql www.mysql.org downloads->进入社区community community 5.7.21 下载5.6 Mic ...