在项目中经常可以看到在类属性上面有一个[]的东西,今天讲的东西就是它,它英文名是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. python 引入本地module

    我们经常会遇到调用组内其他成员开发的python脚本的情况, 这时,需要借助如下代码: import sys sys.path.append('/./..') #/./.. 是需要引入的module的 ...

  2. UNIGUI换版本注意事项

    比如UNIGUI换版本注意事项 许多人在更换UNIGUI版本时,会遇到各种问题,报各样错.比如下面的: 然后便不知所措,怀疑是UNIGUI新版本有问题——不能安装成功.其实不然. 下面是正确的解决方法 ...

  3. unigui1404在delphi10.2.2安装

    unigui1404在delphi10.2.2安装 UNIGUI1404不能直接在DELPHI10.2.2下面编译安装,在10.2.1下面是可以的. 这里讲下怎样安装的方法: 1)执行FMSoft_u ...

  4. nuget.org无法解析的办法

    今天想学习ef框架,就着手安装最新的ef啦.可是遇到了问题,提示 未能解析此远程名称:'nuget.org' 就去上网找资料啦,发现原来是被墙了,表示无奈. 网上的资料提示,修改hosts文件或是dn ...

  5. 实验1 单片机IO口应用及数码管显示

    1.   单片机驱动蜂鸣器的实验: a)         说明:Lab51单片机实验板的蜂鸣器连接到单片机的P1.5 b)        基本要求:控制蜂鸣器每2秒响0.5秒. #include &l ...

  6. Servlet初步认知

    1 背景概述 在近期的公司项目开发的过程中,笔者初步学习Servlet的开发.配置与使用,本文主要介绍了Servlet的相关概念以及优势说明并附上笔者开发简单样例.今天将笔者学习的心得总结出来与大家分 ...

  7. Android------TabLayout的使用

    https://www.jianshu.com/p/2b2bb6be83a8 主要放在 -------> Design库中的TabLayout的使用. margin和padding的区别 外边距 ...

  8. <meta http-equiv="X-UA-Compatible" content="ie=edge">的意思

    <meta http-equiv="X-UA-Compatible" content="ie=edge">vscode创建html文件默认有这串代码 ...

  9. 给Ubuntu18.04安装mac os主题<转载>

     给Ubuntu18.04安装mac os主题 转载来自 https://www.cnblogs.com/feipeng8848(作者) 参考文献 https://linuxhint.com/gnom ...

  10. 常用Yum镜像源

    163网易的yum源 wget http://mirrors.163.com/.help/CentOS6-Base-163.repo sohu的yum源 wget http://mirrors.soh ...