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 = 0; 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 = 0; 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 = 1,
        //
        // 摘要:
        //     可以对模块应用属性。
        Module = 2,
        //
        // 摘要:
        //     可以对类应用属性。
        Class = 4,
        //
        // 摘要:
        //     可以对结构应用属性,即值类型。
        Struct = 8,
        //
        // 摘要:
        //     可以对枚举应用属性。
        Enum = 16,
        //
        // 摘要:
        //     可以对构造函数应用属性。
        Constructor = 32,
        //
        // 摘要:
        //     可以对方法应用属性。
        Method = 64,
        //
        // 摘要:
        //     可以对属性 (Property) 应用属性 (Attribute)。
        Property = 128,
        //
        // 摘要:
        //     可以对字段应用属性。
        Field = 256,
        //
        // 摘要:
        //     可以对事件应用属性。
        Event = 512,
        //
        // 摘要:
        //     可以对接口应用属性。
        Interface = 1024,
        //
        // 摘要:
        //     可以对参数应用属性。
        Parameter = 2048,
        //
        // 摘要:
        //     可以对委托应用属性。
        Delegate = 4096,
        //
        // 摘要:
        //     可以对返回值应用属性。
        ReturnValue = 8192,
        //
        // 摘要:
        //     可以对泛型参数应用属性。
        GenericParameter = 16384,
        //
        // 摘要:
        //     可以对任何应用程序元素应用属性。
        All = 32767
    }
时间: 2024-08-04 18:35:25

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

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

之前我在文章通过Roslyn体验C# 6.0的新语法中介绍了一些C# 6.0的语法特性,现在随着Visual Studio 14 CTP3的发布,又陆续可以体验一些新的特性了,这里简单的介绍一下之前没有介绍的新语法. 属性表达式(Property Expressions) 我们常常会在类中写一些通过函数生成的只读属性: ????class Point????{????????public int X { get; set; }????????public int Y { get; set; }

Atitit.&#160;&#160;c#&#160;语法新特性&#160;c#2.0&#160;3.0&#160;4.0&#160;4.5&#160;5.0&#160;6.0&#160;&#160;&#160;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. C# 2.0的另一个突出的特性就是匿名方法 1.4. C#3.0 linq 1.5. C# 4.0动态编程 dynamic 1.6. C# 4.5 异步编程 async和await 1.7. C# 5.0 更方便的一步编程 1.8. C# 6.0 中的新特性 作者:: 绰号:老哇的爪子 ( 全名:

iOS 语法新特性-modern syntax(iOS6后,Xcode4.4后,OS X 10.8.2后)

- (void)modernSyntax { /* 一.语法新特性NSNumber.NSArray.NSDictionary*/ // ---- NSNumber 新语法 ---- NSNumber *num = nil; // num = [NSNumber numberWithInt:1]; num = @1; // numberWithInt/numberWithShort num = @1u; // numberWithUnsignedInt/numberWithUnsignedShor

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

1 函数基本语法及特性 定义: 函数是指将一组语句的集合通过一个名字(函数名)封装起来,要想执行这个函数,只需调用其函数名即可 特性: 减少重复代码 使程序变的可扩展 使程序变得易维护 语法定义: 1 def sayhi():#函数名 2 print("Hello, I'm nobody!") 3 4 sayhi() #调用函数 可以带参数 1 #下面这段代码 2 a,b = 5,8 3 c = a**b 4 print(c) 5 6 7 #改成用函数写 8 def calc(x,y)

python-函数基本语法及特性

函数是什么? 函数一词来源于数学,但编程中的「函数」概念,与数学中的函数是有很大不同的,具体区别,我们后面会讲,编程中的函数在英文中也有很多不同的叫法.在BASIC中叫做subroutine(子过程或子程序),在Pascal中叫做procedure(过程)和function,在C中只有function,在Java里面叫做method. 定义: 函数是指将一组语句的集合通过一个名字(函数名)封装起来,要想执行这个函数,只需调用其函数名即可 特性: 减少重复代码 使程序变的可扩展 使程序变得易维护

看过这张图你还记不牢JavaScript的语法和特性,算我输!

逛知乎的时候发现@DDDD转了一张图,这张图对js魔法的吐槽可谓非常到位.下面,我们就从这张图出发来详细讲讲js. 数字类型与精度问题 虽然js是弱类型语言,声明变量时也不需要显式指定类型.但是,数据本身依旧还是有类型的,比如数字和字符串就是以不同形式存在的数据.在js中,所有数字的类型都为number.其中,一个特殊的数字就是NaN(Not a number),虽然名字叫"不是数",但为了计算的一致性(IEEE745亦规定),NaN依旧是数字类型的.任何NaN参与的数字计算的结果都还

ECMAScript新语法、特性总结

前言 从2015年的ES6开始,JavaScript的语言标准每年都在更新,其中尤其以ES6的力度之大,到现在ES10已经发布,这里总结一下新语法. 参考:阮一峰 ECMAScript 6 教程 .ECMAScript 6入门 .1.5万字概括ES6全部特性 声明变量 const   块级作用域,变量被const声明后不允许改变,通常在声明时定义 let 块级作用域 注意点: 变量提升: var存在变量提升,const.let不存在变量提升,意思是:var声明的变量在声明之前可以访问,访问到的值

Perl 语法 - 高级特性

总结: q().qq().qw().qx(),分别是单引号.双引号.创建字符串列表 和 捕获命令输出.   第9学时 其他函数和运算符 一件事情可以使用多种方法完成. 本节主要内容: 如何对标量进行简单的字符串搜索?(之前用正则表达式) 如何进行字符替换? 如何使用print函数 如何将数组用作堆栈和队列   第10学时 文件与目录 获得目录列表 创建和删除文件 创建和删除目录 获取文件信息 如何获得目录列表?(打开目录 读取目录) 此步的局限性:只能查看指定目录下的文件目录列表信息. 打开文件

函数基本语法及特性 (一)

我先复制了下面一段,挺有意思的. 背景提要 现在老板让你写一个监控程序,监控服务器的系统状况,当cpu\memory\disk等指标的使用量超过阀值时即发邮件报警,你掏空了所有的知识量,写出了以下代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 while True:     if cpu利用率 > 90%:         #发送邮件提醒         连接邮箱服务器         发送邮件         关闭连接          if 硬