在项目中经常可以看到在类属性上面有一个[]的东西,今天讲的东西就是它,它英文名是Attribute,中文名是特性。

一、什么是特性?

首先,我们肯定Attribute是一个类,下面是msdn文档对它的描述:
公共语言运行时允许你添加类似关键字的描述声明,叫做attributes, 它对程序中的元素进行标注,如类型、字段、方法和属性等。Attributes和Microsoft .NET Framework文件的元数据保存在一起,可以用来向运行时描述你的代码,或者在程序运行的时候影响应用程序的行为。

在.NET中,Attribute被用来处理多种问题,比如序列化、程序的安全特征、防止即时编译器对程序代码进行优化从而代码容易调试等等。下面,我们先来看几个在.NET中标准的属性的使用,稍后我们再回过头来讨论Attribute这个类本身。(文中的代码使用C#编写,但同样适用所有基于.NET的所有语言)。上面的解释说实话这是我复制粘贴的。

二、自定义特性

除了C#中系统自带的特性外我们可以自己定义一些特性。所有自定义的Attribute必须从Attribute类派生,命名也是要以Attribute结尾,在使用的时候可以省略Attribute。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace CusAttribute
{
[AttributeUsage(AttributeTargets.Class,AllowMultiple =true,Inherited =false)]
public class CustomAttribute:System.Attribute
{
public string CustormDescription { get; } public CustomAttribute(string des)
{
CustormDescription = des;
}
}
}

在上面的代码中定义了一个CustomAttribute特性,继承自Attribute类,主要功能是为类添加描述信息。不过在类声明的上一行有一个中括号[AttributeUsage(AttributeTargets.Class,AllowMultiple =true,Inherited =false)] ,这里面的AttributeUsage又是什么玩意呢?我们可以转到定义来看一下:

看定义可以看到,AttributeUsage其实也是继承自Attribute,也是一个特性。那来说下这个类里面的3个属性validOn、AllowMultiple、Inherited.

1.validOn:可以看到它是AttributeTargets类型,而AttributeTargets转到定义可以看到是一个枚举类型。指明Attribute 可以被施加的元素的类型。

2.AllowMultiple:它是一个布尔值。表示是否可以对一个程序元素施加多个Attribute。

3.Inherited:它也是一个布尔值,表示是否施加的Attribute 可以被派生类继承或者重载

使用下面的代码一步一步验证上面的3个属性。

我们定义了一个Person基类,定义了Student类继承自Person类。

1.AllowMultiple

将上面的特性设置为[AttributeUsage(AttributeTargets.Class,AllowMultiple =true,Inherited =false)]时

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace CusAttribute
{
[CustomAttribute("人")]
[Custom("基类")]
public class Person
{ public string Name { get; set; } public int Age { get; set; }
}
}

上面使用两次特性,也是没有报错是可以的,但是如果AllowMultiple设为false,编译时就会报错.

2.Inherited

先把Student、Person类也贴出来

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace CusAttribute
{
[CustomAttribute("学生")]
public class Student:Person
{
public string StudentId { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace CusAttribute
{
//[CustomAttribute("人")]
[Custom("基类")]
public class Person
{ public string Name { get; set; } public int Age { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace CusAttribute
{
class Program
{
static void Main(string[] args)
{ System.Reflection.MemberInfo info = typeof(Student);
object[] attributes = info.GetCustomAttributes(true);
for (int i = ; i < attributes.Length; i++){
CustomAttribute attr = (CustomAttribute)attributes[i];
System.Console.WriteLine("{0} {1}", attr.CustormDescription, attributes[i]);
} Console.WriteLine("-----------------------");
info = typeof(Person);
attributes = info.GetCustomAttributes(true);
for (int i = ; i < attributes.Length; i++)
{
CustomAttribute attr = (CustomAttribute)attributes[i];
System.Console.WriteLine("{0} {1}",attr.CustormDescription,attributes[i]);
}
Console.ReadLine();
}
}
}

在main方法中我们Student和Person类中的特性并输出,通过反射,至于反射以后会有提到

和AllowMultiple一起有4种可能性.

AllowMultiple:false      Inherited:true

AllowMultiple:false      Inherited:false

AllowMultiple:true  Inherited:false

AllowMultiple:true  Inherited:true

对于Inherited:false时就不说了,不能被派生类继承,当Inherited:true时,AllowMultiple:true的话派生类不会覆盖父类的特性,AllowMultiple:false的话派生类会覆盖父类的特性。

3.validOn

这个主要是一个枚举。可以看下枚举都有什么.也就是说可以将特性应用到下面的枚举类型中。

  //
// 摘要:
// 指定可以对它们应用特性的应用程序元素。
[ComVisible(true)]
[Flags]
public enum AttributeTargets
{
//
// 摘要:
// 可以对程序集应用属性。
Assembly = ,
//
// 摘要:
// 可以对模块应用属性。
Module = ,
//
// 摘要:
// 可以对类应用属性。
Class = ,
//
// 摘要:
// 可以对结构应用属性,即值类型。
Struct = ,
//
// 摘要:
// 可以对枚举应用属性。
Enum = ,
//
// 摘要:
// 可以对构造函数应用属性。
Constructor = ,
//
// 摘要:
// 可以对方法应用属性。
Method = ,
//
// 摘要:
// 可以对属性 (Property) 应用属性 (Attribute)。
Property = ,
//
// 摘要:
// 可以对字段应用属性。
Field = ,
//
// 摘要:
// 可以对事件应用属性。
Event = ,
//
// 摘要:
// 可以对接口应用属性。
Interface = ,
//
// 摘要:
// 可以对参数应用属性。
Parameter = ,
//
// 摘要:
// 可以对委托应用属性。
Delegate = ,
//
// 摘要:
// 可以对返回值应用属性。
ReturnValue = ,
//
// 摘要:
// 可以对泛型参数应用属性。
GenericParameter = ,
//
// 摘要:
// 可以对任何应用程序元素应用属性。
All =
}

C#语法之特性的更多相关文章

  1. Python3学习之路~3.1 函数基本语法及特性、返回值、参数、局部与全局变量

    1 函数基本语法及特性 定义: 函数是指将一组语句的集合通过一个名字(函数名)封装起来,要想执行这个函数,只需调用其函数名即可 特性: 减少重复代码 使程序变的可扩展 使程序变得易维护 语法定义: d ...

  2. Java7语法新特性

    Java7语法新特性: 1. switch中增加对String类型的支持. public String generate(String name, String gender) { String ti ...

  3. Python面向对象学习2(面向对象的语法和特性,待更新)

    上一个内容我们介绍了面向对象和面向对象场景现在我们来学习下语法和特性 1,面向对象基本语法: # -*- coding:utf-8 -*- # Author: Colin Yao class Dog( ...

  4. Atitit.  c# 语法新特性 c#2.0 3.0 4.0 4.5 5.0 6.0   attilax总结

    Atitit.  c# 语法新特性 c#2.0 3.0 4.0 4.5 5.0 6.0   attilax总结 1.1. C# 1.0-纯粹的面向对象 1.2. C# 2.0-泛型编程新概念 1.3. ...

  5. day03 函数基本语法及特性 2. 参数与局部变量 3. 返回值 嵌套函数 4.递归 5.匿名函数 6.函数式编程介绍 7.高阶函数 8.内置函数

    本节内容 1. 函数基本语法及特性 2. 参数与局部变量 3. 返回值 嵌套函数 4.递归 5.匿名函数 6.函数式编程介绍 7.高阶函数 8.内置函数 温故知新 1. 集合 主要作用: 去重 关系测 ...

  6. Perl 语法 - 高级特性

    总结: q().qq().qw(同单引号).qx{牢记是花括号},分别是单引号.双引号.创建字符串列表 和 捕获命令输出.   第9学时 其他函数和运算符 一件事情可以使用多种方法完成. 有哪些其他的 ...

  7. C# 6.0语法新特性体验(二)

    之前我在文章通过Roslyn体验C# 6.0的新语法中介绍了一些C# 6.0的语法特性,现在随着Visual Studio 14 CTP3的发布,又陆续可以体验一些新的特性了,这里简单的介绍一下之前没 ...

  8. Erlang学习记录:语法和特性

    特性 大下排序:number < atom < reference < fun < port < pid < tuple < list < bit st ...

  9. ECMAScript新语法、特性总结

    前言 从2015年的ES6开始,JavaScript的语言标准每年都在更新,其中尤其以ES6的力度之大,到现在ES10已经发布,这里总结一下新语法. 参考:阮一峰 ECMAScript 6 教程 .E ...

  10. Java 7 语法新特性

    一.二进制数字表达方式 原本整数(以60为例)能够用十进制(60).八进制(074).十六进制(0x3c)表示,唯独不能用二进制表示(111100),Java 7 弥补了这点. public clas ...

随机推荐

  1. GetFileOpenName()、GetFilesavename

    GetFileOpenName() 功能显示打开文件对话框,让用户选择要打开的文件. 语法:GetFileOpenName(title,pathname,filename{,extension{,fi ...

  2. 第二天:Javascript事件

    事件:是可以被Javascript侦测到的行为,例如鼠标的点击,鼠标的移动,常见的事件如下   代码实现“点击事件”: <body> <button onclick="de ...

  3. centos7 搭建WEB服务器

    centos7 搭建WEB服务器 2017年09月17日 09:44:50 逝然1994 阅读数:18321 标签: centosapacheweb服务器 更多 个人分类: centos服务器简单配置 ...

  4. Delphi 在DLL中使用DevExpress控件时出错解决办法

    测试环境 DevExpress VCL 14.1.3 和XE7 问题:在dll使用cxGrid控件时  如果不添加列标题 则不报错   查询无数据集显示,如果加上标题 就报错了 这段为报错部分 fun ...

  5. 从工程化角度讨论如何快速构建可靠React组件

    前言 React 的开发也已经有2年时间了,先从QQ的家校群,转成做互动直播,主要是花样直播这一块.切换过来的时候,业务非常繁忙,接手过来的业务比较凌乱,也没有任何组件复用可言. 为了提高开发效率,去 ...

  6. mysql存储过程双重循环示例

    BEGIN ); DECLARE done INT DEFAULT FALSE; DECLARE cursor_rule CURSOR FOR SELECT s.id FROM d_menu_type ...

  7. JavaScript(JS)简介

    历史背景介绍 (Brendan Eich)在其Netscape Navigator 2.0产品中开发出一套livescript的脚本语言.Sun和Netscape共同完成.后改名叫Javascript ...

  8. 使用Express构建RESTful API

    RESTful服务 REST(Representational State Transfer)的意思是表征状态转移,它是一种基于HTTP协议的网络应用接口风格,充分利用HTTP的方法实现统一风格接口的 ...

  9. odoo开发笔记 -- 视图继承扩展

    参考: http://www.jeffzhang.cn/Odoo-Notes-2/ http://blog.csdn.net/zhangfeng1133/article/details/4693517 ...

  10. 消息队列系统 -- RabbitMQ

    消息队列系统 -- RabbitMQ RabbitMQ是一个在AMQP基础上完整的,可复用的企业消息系统.他遵循Mozilla Public License开源协议. MQ全称为Message Que ...