在项目中经常可以看到在类属性上面有一个[]的东西,今天讲的东西就是它,它英文名是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. Android学习之可滑动当前的Activity视图看见上一个活动的视图

    先看一下我的效果图吧: 好大的图啊!!! 百度音乐由一个很酷的功能,当前的UI可以滑动,然后看见上一个活动的UI,当时顿时觉得百度的牛人好多啊,能将如此前沿的技术应用到app上.当然如果你熟悉了And ...

  2. 在windows右键菜单中加入自己的程序 [转载]

    原文链接: http://blog.csdn.net/marklr/article/details/4006356  在windows右键菜单中加入自己的程序 标签: windowsattribute ...

  3. .net MVC, webAPI,webForm集成steeltoe+springcloud实现调用服务中心服务的总结

    开始之前,如果没接触过Autofac的,可以移步到Autofac官方示例学习一下怎么使用:https://github.com/autofac/Examples .net 下集成steeltoe进行微 ...

  4. python安装mysql-python依赖包

    # 背景 新公司,对换工作了!接口自动化使用的是python的behave框架,因此需要折腾python了,而公司配的笔记本是windows的,因此要在windows下折腾python了 # 步骤 项 ...

  5. mysql5.7 安装错误解决

    1.5.7初始化报错 2019-04-29 21:40:34 [ERROR] Child process: /home/work/mysql/bin/mysqldterminated prematur ...

  6. sam(后缀自动机)

    后缀自动机ins解释 void ins(int c){ int p=last;//将当前节点的parent节点变为last int np=++cnt;//建立新节点 last=np;//将last设为 ...

  7. 使用 kafkat 在线扩缩容 kafka replicas

    本文档应用环境为 kafka-0.8.2.0, 其余版本请先行测试 场景 线上很多 kafka 的 topic 的副本数为1,这样的设置丧失了 kafka 高可用的特性,所以我们需要把 topic 的 ...

  8. activemq在一台服务器上启动多个Broker

    步骤如下: 1.把整个conf文件夹复制一份,比如叫conf2 2.修改里面的activemq.xml文件 ①brokerName不能和原来的重复 ②数据存放的文件名称不能重复,比如<kahaD ...

  9. Django admin argument to reversed() must be a sequence

    django执行反序列化操作老是报Django admin argument to reversed() must be a sequence 切记查看所有的路由设置,主路由(urls)和分的都要修改 ...

  10. 【spring揭秘】1、关于IOC的基础概念

    1.基础概念 IOC有三种注入方式: 1.构造方法注入,就是通过构造方法进行实例化成员属性对象,优点是实现对象之后直接就可以使用,但是参数过多也是个麻烦 2.setter方法注入,实现相应的sette ...