Attribute介绍

咱们来说Attribute,他是一个类,所以自定义的Attribute都是继承自System.Attribute,一般命名的时候都是以Attribute结尾。在使用的时候我们可以省去Attribute,比如我们自定义一个IsEatAttribute那么在我们使用的时候就可以这样来写[IsEat],Attribute类在定义的时候,可以指定这个Attribute的应用范围,AttributeTargets枚举就列出了可以指定的范围,可以是class,也可以全部指定。就像这样:(Attribute必须写在一对方括符中)。

[AttributeUsage(AttributeTargets.Class)]

[AttributeUsage(AttributeTargets.All)]

这是使用时候。

先看一个自带的Attribute.

Attribute 的作用

特性Attribute 的作用是添加元数据。
元数据可以被工具支持,比如:编译器用元数据来辅助编译,调试器用元数据来调试程序。

Attribute是程序代码的一部分,不但不会被编译器丢弃,而且还会被编译器编译进程序集(Assembly)的元数据(Metadata)里,在程序运行的时候,你随时可以从元数据里提取出这些附加信息来决策程序的运行。

---------------------------------------------------------------

自定义一个Attribute

现在我们就来自定义一个Attribute。我们目的是要分为:好人和坏人。好人我们给饭吃,坏人我们不给饭吃。添加一个类,定义如下:

namespace _Attribute
{
    [AttributeUsage(AttributeTargets.Class)]
    public class IsEatAttribute:Attribute
    {
        public enum Appoint  //我首先定义一个枚举类型的指定。Appoint指定
        {
            good,
            bad
        };
        public Appoint _Appoint { get; set; }   //封装了起来,在用的时候使用形参进行赋值
        //public int id(get;set;)
        public IsEatAttribute(Appoint appoint)
        {
            _Appoint = appoint;
        }
    }
}

IsEatAttribute继承了Attribute.我们定义了一个枚举类型的Appoint分为好和坏。在这个类里面我们声明了一个枚举类型的_Appoint变量。并给它封装起来。你可以看到类名和下面那个方法名相同,可以看出它是一个构造函数。我们给它一个形参列表,用于给_Appoint赋值。

定义接口:

namespace _Attribute
{
    public interface IMan
    {
        string Show();
    }
}

使用Attribute

我们自定义了一个Attribute,下面我们来使用它。
GoodMan.cs

namespace _Attribute
{
    [IsEat(IsEatAttribute.Appoint.good)]
    public class GoodMan:IMan
    {
        public string Show()
        {
           return "这是一个好人,好人可以吃饭";
        }
    }
}

我们在类上面Appoint(指明)了good。

BadMan.cs

namespace _Attribute
{
    [IsEat(IsEatAttribute.Appoint.bad)]
    public class BadMan:IMan
    {
        public string Show()
        {
           return "这是一个坏人,坏人不给饭吃";
        }
    }
}

我们在类上面Appoint(指明)了bad。

Attribute过滤

接下来我们还是要添加一个类,Filter.

namespace _Attribute
{
    public class Filter
    {
        public static void Leach(IMan man)
        {
            System.Reflection.MemberInfo info = man.GetType(); //通过反射得到man的信息
            //MethodInfo获取有关成员属性的信息,并提供对成员元数据的访问
            IsEatAttribute attribute = (IsEatAttribute)Attribute.GetCustomAttribute(info, typeof(IsEatAttribute));
                            //获取当前类的标签,然后用标签与传进来的info进行比较,确认man类型.
            //得到施加在man上定制的Attribute
            if (attribute._Appoint == IsEatAttribute.Appoint.good)
                Console.WriteLine(man.GetType().ToString() + ":" + man.Show());
            else
                Console.WriteLine(man.GetType().ToString() + ":" + "这是坏人");
        }
    }
}

static Attribute GetCustomAttribute():这个方法有8种重载的版本,它被用来取出施加在类成员上指定类型的Attribute。(这是我最难理解的地方)

来说一下为什么要用一个Filter来声明一个Leach过滤方法呢?因为,如果我们不通过过滤就去实例化对象,并且调用类里面的方法的话,就不会达到我们预期的效果。

看一次测试结果:

如果我们把GoodMan类上的Attribute指定成bad类,那么会出现如下结果:

[IsEat(IsEatAttribute.Appoint.bad)]
public class GoodMan:IMan

总结:

Property一般是指一对get,set方法,可以称为是类的成员属性,它大部分时候用来对类的成员变量进行读取或赋值。

Attributes的解释如下:
公共语言运行时允许你添加类似关键字的描述声明,叫做attributes, 它对程序中的元素进行标注,如类型、字段、方法和属性等。可以用来向运行时描述你的代码,或者在程序运行的时候影响应用程序的行为。
说的通俗些Attribute是类,不过是一类比较特殊的类,Attribute必须写在一对方括号中,用来处理.net中多种问题:序列化、程序的安全特征等等.

扩展

Attribute
除了.NET提供的那些Attribute派生类之外,我们可以自定义我们自己的Attribute,所有自定义的Attribute必须从Attribute类派生。现在我们来看一下Attribute 类的细节:

protected Attribute(): 保护的构造器,只能被Attribute的派生类调用。

三个静态方法:

static Attribute GetCustomAttribute():这个方法有8种重载的版本,它被用来取出施加在类成员上指定类型的Attribute

static Attribute[] GetCustomAttributes(): 这个方法有16种重载版本,用来取出施加在类成员上指定类型的Attribute数组。

static bool IsDefined():由八种重载版本,看是否指定类型的定制attribute被施加到类的成员上面。

实例方法:

bool IsDefaultAttribute(): 如果Attribute的值是默认的值,那么返回true。

bool Match():表明这个Attribute实例是否等于一个指定的对象。

公共属性: TypeId: 得到一个唯一的标识,这个标识被用来区分同一个Attribute的不同实例。

我们简单地介绍了Attribute类的方法和属性,还有一些是从object继承来的。这里就不列出来了。

下面介绍如何自定义一个Attribute: 自定义一个Attribute并不需要特别的知识,其实就和编写一个类差不多。自定义的Attribute必须直接或者间接地从Attribute这个类派生,如:

public MyCustomAttribute : Attribute { ... }

这里需要指出的是Attribute的命名规范,也就是你的Attribute的类名+"Attribute",当你的Attribute施加到一个程序的元素上的时候,编译器先查找你的Attribute的定义,如果没有找到,那么它就会查找“Attribute名称"+Attribute的定义。如果都没有找到,那么编译器就报错。

对于一个自定义的Attribute,你可以通过AttributeUsage的Attribute来限定你的Attribute所施加的元素的类型。代码形式如下: [AttriubteUsage(参数设置)] public 自定义AttributeAttribute { ... }

非常有意思的是,AttributeUsage本身也是一个Attribute,这是专门施加在Attribute类的Attribute. AttributeUsage自然也是从Attribute派生,它有一个带参数的构造器,这个参数是AttributeTargets的枚举类型。

Attribute的更多相关文章

  1. [C#] 剖析 AssemblyInfo.cs - 了解常用的特性 Attribute

    剖析 AssemblyInfo.cs - 了解常用的特性 Attribute [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/5944391.html 序 ...

  2. JavaScript特性(attribute)、属性(property)和样式(style)

    最近在研读一本巨著<JavaScript忍者秘籍>,里面有一篇文章提到了这3个概念. 书中的源码可以在此下载.我将源码放到了线上,如果不想下载,可以直接访问在线网址,修改页面名就能访问到相 ...

  3. [C#] C# 知识回顾 - 特性 Attribute

    C# 知识回顾 - 特性 Attribute [博主]反骨仔 [原文地址]http://www.cnblogs.com/liqingwen/p/5911289.html 目录 特性简介 使用特性 特性 ...

  4. js attribute 和 jquery attr 方法

    attribute 是原生js dom 对象上的一个属性,这个属性有很多子属性,比如 isId(判断属性是否是Id) , name (获取属性名称) , value (获取属性值),attribute ...

  5. 【.net 深呼吸】自定义特性(Attribute)的实现与检索方法

    在.net的各个语言中,尤其是VB.NET和C#,都有特性这一东东,具体的概念,大家可以网上查,这里老周说一个非标准的概念——特性者,就是对象的附加数据.对象自然可以是类型.类型成员,以及程序集. 说 ...

  6. angular2系列教程(四)Attribute directives

    今天我们要讲的是ng2的Attribute directives.顾名思义,就是操作dom属性的指令.这算是指令的第二课了,因为上节课的components实质也是指令. 例子

  7. 学会给你的类(及成员)来定制一套自己的Attribute吧

    在通过Visual Studio创建的C#程序集中,都包含了一个AssemblyInfo.cs的文件,在这个文件中,我们常常会看到这样的代码 [assembly: AssemblyTitle(&quo ...

  8. Attribute操作的性能优化方式

    Attribute是.NET平台上提供的一种元编程能力,可以通过标记的方式来修饰各种成员.无论是组件设计,语言之间互通,还是最普通的框架使 用,现在已经都离不开Attribute了.迫于Attribu ...

  9. SharePoint 2016 配置向导报错 - The 'ListInternal' attribute is not allowed

    前言 配置SharePoint 2016的配置向导中,第三步创建配置数据库报错,然后百度.谷歌了一下,都没有解决,自己看日志搞定,也许会有人遇到类似问题,分享一下. 1.配置向导的错误截图,如下图: ...

  10. C# 知识特性 Attribute

    C#知识--获取特性 Attribute 特性提供功能强大的方法,用以将元数据或声明信息与代码(程序集.类型.方法.属性等)相关联.特性与程序实体关联后,可在运行时使用"反射"查询 ...

随机推荐

  1. windows下Bat命令学习

    一.基础语法:1.批处理文件是一个“.bat”结尾的文本文件,这个文件的每一行都是一条DOS命令.可以使用任何文本文件编辑工具创建和修改.2.批处理是一种简单的程序,可以用 if 和 goto 来控制 ...

  2. lua协程一则报错解决“attempt to yield across metamethod/C-call boundary”

    问题 attempt to yield across metamethod/C-call boundary 需求跟如下帖子中描述一致: http://bbs.chinaunix.net/forum.p ...

  3. ios-深度解析二维码的生成与使用

    利用一个小demo来对二维码进行学习,总共四个界面(主界面,生成二维码界面,识别二维码界面,扫描二维码界面)   一.二维码的介绍   1.什么是二维码?        二维条码/二维码是用某种特定的 ...

  4. composer--------------通过composer.json下载laravel包----barryvdh/laravel-debugbar

    1.去Packagist网站https://packagist.org/packages/barryvdh/laravel-debugbar#dev-master找到

  5. HTML5的Server-Sent Events介绍////////////////zzz

    HTML5有一个Server-Sent Events(SSE)功能,允许服务端推送数据到客户端.(通常叫数据推送).我们来看下,传统的WEB应用程序通信时的简单时序图: 现在Web App中,大都有A ...

  6. operator->和operator->*

    ->和->*都是C++中定义的可重载的运算符,其中:->称为成员选择符(member selection),而->*称为成员指针选择符(pointer-to-member se ...

  7. 【转帖】ActiveX部件不能创建对象的终极解决方案

    建一个批处理文件,内容如下: echo 正在修复,这个过程可能需要几分钟,请稍候-- rundll32.exe advpack.dll /DelNodeRunDLL32 %systemroot%Sys ...

  8. 【转】sql各种查询技巧

    高级查询在数据库中用得是最频繁的,也是应用最广泛的. Ø 基本常用查询 --select select * from student;   --all 查询所有 select all sex from ...

  9. DOM的基本属性

    结构和内容属性1.1 nodeType1.2 nodeName, tagName1.3 innerHTML1.4 innerHTML pitFalls1.5 nodeValue 总结DOM节点是一个对 ...

  10. C++术语俗解

    C++作为一种复杂的编程语言,其最晦涩的莫过于各个术语. 以下就经常使用的术语,逐个俗解(特别声明:为了对术语的更好理解与记忆,仅代表个人的俗识,若有不妥之处望给予指正),分享共勉. 内存:一片计算机 ...