C#语法之特性
在项目中经常可以看到在类属性上面有一个[]的东西,今天讲的东西就是它,它英文名是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#语法之特性的更多相关文章
- Python3学习之路~3.1 函数基本语法及特性、返回值、参数、局部与全局变量
1 函数基本语法及特性 定义: 函数是指将一组语句的集合通过一个名字(函数名)封装起来,要想执行这个函数,只需调用其函数名即可 特性: 减少重复代码 使程序变的可扩展 使程序变得易维护 语法定义: d ...
- Java7语法新特性
Java7语法新特性: 1. switch中增加对String类型的支持. public String generate(String name, String gender) { String ti ...
- Python面向对象学习2(面向对象的语法和特性,待更新)
上一个内容我们介绍了面向对象和面向对象场景现在我们来学习下语法和特性 1,面向对象基本语法: # -*- coding:utf-8 -*- # Author: Colin Yao class Dog( ...
- 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. ...
- day03 函数基本语法及特性 2. 参数与局部变量 3. 返回值 嵌套函数 4.递归 5.匿名函数 6.函数式编程介绍 7.高阶函数 8.内置函数
本节内容 1. 函数基本语法及特性 2. 参数与局部变量 3. 返回值 嵌套函数 4.递归 5.匿名函数 6.函数式编程介绍 7.高阶函数 8.内置函数 温故知新 1. 集合 主要作用: 去重 关系测 ...
- Perl 语法 - 高级特性
总结: q().qq().qw(同单引号).qx{牢记是花括号},分别是单引号.双引号.创建字符串列表 和 捕获命令输出. 第9学时 其他函数和运算符 一件事情可以使用多种方法完成. 有哪些其他的 ...
- C# 6.0语法新特性体验(二)
之前我在文章通过Roslyn体验C# 6.0的新语法中介绍了一些C# 6.0的语法特性,现在随着Visual Studio 14 CTP3的发布,又陆续可以体验一些新的特性了,这里简单的介绍一下之前没 ...
- Erlang学习记录:语法和特性
特性 大下排序:number < atom < reference < fun < port < pid < tuple < list < bit st ...
- ECMAScript新语法、特性总结
前言 从2015年的ES6开始,JavaScript的语言标准每年都在更新,其中尤其以ES6的力度之大,到现在ES10已经发布,这里总结一下新语法. 参考:阮一峰 ECMAScript 6 教程 .E ...
- Java 7 语法新特性
一.二进制数字表达方式 原本整数(以60为例)能够用十进制(60).八进制(074).十六进制(0x3c)表示,唯独不能用二进制表示(111100),Java 7 弥补了这点. public clas ...
随机推荐
- 数据库索引、B树、B+树
数据库索引,是数据库管理系统中一个排序的数据结构,以协助快速查询.更新数据库表中数据.索引的实现通常使用B树及其变种B+树. 在数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某 ...
- 【C#】转一篇MSDN杂志文:ASP.NET Pipeline: Use Threads and Build Asynchronous Handlers in Your Server-Side Web Code
序:这是一篇发表在2003年6月刊的MSDN Magazine的文章,现在已经不能在线阅读,只提供chm下载.讲的是异步请求处理那些事,正是我上一篇博文涉及的东西(BTW,事实上这篇杂志阐述了那么搞然 ...
- UWP Button添加圆角阴影(一)
原文:UWP Button添加圆角阴影(一) 众所周知,17763之前的UWP控件,大部分是没有圆角属性的:而阴影也只有17763中的ThemeShadow可以直接在xaml中使用,之前的版本只能用D ...
- AngularJS指令封装高德地图组件
1 概述 公司移动门户原来是基于AngularJS指令封装的百度地图组件,用于签到.签退.定位等功能,在使用过程中发现百度地图频繁的弹出广告,所以打算重新引用其它地图组件,最后决定基于AngularJ ...
- AJPFX平台:外汇的基本面分析
AJPFX平台:开设外汇保证金交易账户以及入金之后,通常就可以开始交易了,但是在选择买卖时点时通常会依据两种分析,两种主要分析方法通常会被称为基本面分析和技术分析.基本面分析注重金融,经济理论和政局发 ...
- SDK 上报信息 史上最全 持续更新
SDK 上报信息 史上最全 持续更新 接入SDK总会遇到各种需求,有些SDK巴不得把玩家信息全部上报到他们服务器! 以下是我接SDK遇到的, 欢迎大家补全. 上报事件 注册(按道理这个应该是SDK的功 ...
- Cesium Vue开发环境搭建
最近被问到如何在 vuejs 中集成 cesium,首先想到的官网应该有教程.官网有专门讲 Cesium and Webpack(有坑),按照官网的说明,动手建了一个Demo,在这记录下踩坑过程. 一 ...
- [原创]K8_C段旁注工具6.0 新增SMB漏洞扫描
工具: K8_C段旁注工具6.0_0510[K.8]编译: 自己查壳组织: K8搞基大队[K8team]作者: K8拉登哥哥博客: http://qqhack8.blog.163.com发布: 201 ...
- POJ 2707
#include<iostream> #include<stdio.h> #include<algorithm> using namespace std; int ...
- 关于Mybatis中Mapper是使用XML还是注解的一些思考
XML 据说可以灵活的进行注解,但是修改以后还是要重新发布程序.当然,你可以说,在Tomcat中改了,然后热加载了,不就可以了.可是一般情况下都是几台,十几台服务器.都是用发布系统,持续集成的方式部署 ...