特性
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. 使用C++生成1-33中的6个随机数,无重复

    生成1-33中的6个随机数,无重复 ------------------------------------------------------------------------   方法1.每生成 ...

  2. servlet转发与重定向

    HttpServletRequest: 表示浏览器向服务器发送的请求报文,由Tomcat创建然后作为参数传递给我们doget,dopost方法. 功能:getParameter()获取请求参数 get ...

  3. python调用R语言,关联规则可视化

    首先当然要配置r语言环境变量什么的 D:\R-3.5.1\bin\x64; D:\R-3.5.1\bin\x64\R.dll;D:\R-3.5.1;D:\ProgramData\Anaconda3\L ...

  4. Solr Suggest组件的使用

    使用suggest的原因,最主要就是相比于search速度快,In general, we need the autosuggest feature to satisfy two main requi ...

  5. 第九章 自定义mixer adapter

    1 install/kubernetes/helm/istio/templates/crds.yaml 序号 名称 用途 分类 归属 virtualservices.networking.istio. ...

  6. Asp.netMVC中地址后缀使用.html,jsp等404错误解决

    asp.net mvc 默认的地址路径url都是没有后缀的比如 www.a.com/aa/bb 等 如果要是www.a.com/aa/bb.html需要专门写路由. 根据我之前的经验,mvc的路由是相 ...

  7. Loadrunner11在新建Microsoft Word 报告时提示指定的转换无效

    HP Loadrunner11中文教程的学习基本已经结束,最后困扰我的就是这个在创建Microsoft Word 报告时不停的提示“指定的转换无效”的问题.在网上搜索了好长时间,好多朋友回答说没有生成 ...

  8. selenium+python自动化79-文件下载(SendKeys)

    前言 文件下载时候会弹出一个下载选项框,这个弹框是定位不到的,有些元素注定定位不到也没关系,就当没有鼠标,我们可以通过键盘的快捷键完成操作. SendKeys库是专业的处理键盘事件的,所以这里需要用S ...

  9. 20165233 实验一 Java开发环境的熟悉

    20165233 实验一 Java开发环境的熟悉 实验要求 1.没有Linux基础的同学建议先学习<Linux基础入门(新版)><Vim编辑器> 课程: 2.完成实验.撰写实验 ...

  10. jeesite快速开发平台(五)----用户-角色-部门-区域-菜单-权限表关系

    转自: https://blog.csdn.net/u011781521/article/details/78994904