浅析C#中的Attribute[转]

首先贴出原文作者和地址,以表示感谢。

原文作者:hyddd

原文地址:http://www.cnblogs.com/hyddd/

正文:

一.什么是Attribute

先看下面的三段代码:

1.自定义Attribute类:VersionAttribute

    [AttributeUsage(AttributeTargets.Class)]
    public class VersionAttribute : Attribute
    {
        public string Name { get; set; }
        public string Date { get; set; }
        public string Describtion { get; set; }
    }

2.使用自定义Attribute的Class:

    [Version(Name = "hyddd", Date = "2009-07-20", Describtion = "hyddd‘s class")]
    public class MyCode
    {
        //...
    }

3.上面这个Class中的Attribute一般会被如何使用呢?

    class Program
    {
        static void Main(string[] args)
        {
            var info = typeof(MyCode);
            var classAttribute = (VersionAttribute)Attribute.GetCustomAttribute(info, typeof(VersionAttribute));
            Console.WriteLine(classAttribute.Name);
            Console.WriteLine(classAttribute.Date);
            Console.WriteLine(classAttribute.Describtion);
        }
    }

示例完毕!上面三段代码相信已经说明了Attribute大概是一个什么东西和怎么去用。

二.深入讨论Attribute

1.Attribute的概念定义

关于Attribute概念的定义,我直接引用《你必须知道的.NET之特性和属性》中的一段来说明:

     MADN的定义为:公共语言运行时允许添加类似关键字的描述声明,叫做attributes, 它对程序中的元素进行标注,如类型、字段、方法和属性等。Attributes和Microsoft .NET Framework文件的元数据(metadata)保存在一起,可以用来向运行时描述你的代码,或者在程序运行的时候影响应用程序的行为。

我们简单的总结为:定制特性attribute,本质上是一个类,其为目标元素提供关联附加信息,并在运行期以反射的方式来获取附加信息。

噢,原来Attribute的目的是为元素提供关联附加信息。其中,上面第一段代码中“[AttributeUsage(AttributeTargets.Class)] ”说明了Attribute提供附加信息的元素是Class,所以如果上面第二段的代码改为:

public class MyCode
{
    [Version(Name = "hyddd", Date = "2009-07-20", Describtion = "hyddd‘s class")]
    public void Test() { }
}

会出现编译错误。

2.Attribute作为编译指令

Attribute类是在编译的时候被实例化的,而不是像通常的类那样在运行时候才实例化。所以在第三段代码中,你可以在没有实例化MyCode对象的情况下取到MyCode的Attribute信息。由于Attribute类是在编译的时候被实例化的,所以你还可以用外部工具维护这些Attribute信息。

3.Attribute与Property

从中文来说,Attribute和Property的中文都叫“属性”,很容易让人混淆。现在的文章,Attribute一般翻译为”特性”,而Property称为“属性”。

或许你会问,我用静态的Property/Field一样可以做到在不实例化的时候拿到一些信息,如果这样的话,Attribute又有什么存在意义呢?

1.Property:

Property可以说是一个面向对象的概念,提供了对私有字段的访问封装,在C#中以get和set访问器方法实现对可读可写属性的操作,提供了安全和灵活的数据访问封装。比如:

    public class Robot
    {
        private string name = "";   //字段:Field
        public string Name          //属性:Property,对Field进行封装。
          {
            get { return name; }
            set { name = value; }
        }
    }

2.Attribute:

Attribute的目标是:为元素提供附加信息。它的作用更类似于注释。

可以说,Property/Field和Attribute是两个完全不同的概念,虽然他们有些时候能做一样的事,但请记住,他们是从本质上就不同的两个东西。

三.实现自己的Attribute时需要注意的一些问题

1.自定义的Attribute必须直接或者间接继承System.Attribute。

2.这里有一个约定:所有自定义的特性名称都应该有个Attribute后缀。因为当你的Attribute施加到一个程序的元素上的时候,编译器先查找你的Attribute的定义,如果没有找到,那么它就会查找“Attribute名称"+Attribute的定义。如果都没有找到,那么编译器就报错。这就是为什么我可以再上面第一段代码中,定义一个VersionAttribute,但在第二段代码中,我使用却是Version这个Attribute。:>

下面是一些开发自定义Attribute时,可能需要用到的资料:

【1】Attribute可以关联的元素包括:

程序集(assembly)、模块(module)、类型(type)、属性(property)、事件(event)、字段(field)、方法(method)、参数(param)、返回值(return)。例如:

    [assembly: Version(Name = "hyddd", Date = "2009-07-20", Describtion = "hyddd‘s class")]
    public class MyCode
    {
        //......
    }

用指定的前缀来表示特性所应用的目标元素,建议这样来处理,因为显式处理可以消除可能带来的二义性。

【2】AttributeTargets目标包括:

标记 说明
All 可以对任何应用程序元素应用属性。
Assembly 可以对程序集应用属性。 
Class 可以对类应用属性。
Constructor 可以对构造函数应用属性。
Delegate 可以对委托应用属性。
Enum 可以对枚举应用属性。
Event 可以对事件应用属性。
Field 可以对字段应用属性。
GenericParameter 可以对泛型参数应用属性。
Interface 可以对接口应用属性。
Method 可以对方法应用属性。
Module Module 指的是可移植的可执行文件(.dll 或 .exe),而非 Visual Basic 标准模块。
Parameter 可以对参数应用属性。
Property 可以对属性 (Property) 应用属性 (Attribute)。
ReturnValue 可以对返回值应用属性。
Struct 可以对结构应用属性,即值类型。

【3】AttributeUsageAttribute中的3个属性(Property)说明:

属性名 说明
ValidOn 该定位参数指定可在其上放置所指示的属性 (Attribute) 的程序元素。AttributeTargets 枚举数中列出了可在其上放置属性 (Attribute) 的所有可能元素的集合。可通过按位“或”运算组合多个 AttributeTargets 值,以获取所需的有效程序元素组合。
AllowMultiple 该命名参数指定能否为给定的程序元素多次指定所指示的属性。
Inherited 该命名参数指定所指示的属性能否由派生类和重写成员继承。
时间: 2024-10-09 00:46:38

浅析C#中的Attribute[转]的相关文章

转浅析C#中的Attribute

一.什么是Attribute 先看下面的三段代码: 1.自定义Attribute类:VersionAttribute [AttributeUsage(AttributeTargets.Class)] public class VersionAttribute : Attribute { public string Name { get; set; } public string Date { get; set; } public string Describtion { get; set; }

浅析C#中的Attribute

1.什么是Attribute? 特性(Attribute)是用于在运行时传递程序中各种元素(比如类.方法.结构.枚举.组件等)的行为信息的声明性标签.您可以通过使用特性向程序添加声明性信息.一个声明性标签是通过放置在它所应用的元素前面的方括号([ ])来描述的. 特性(Attribute)用于添加元数据,如编译器指令和注释.描述.方法.类等其他信息..Net 框架提供了两种类型的特性:预定义特性和自定义特性. 规定特性(Attribute) 规定特性(Attribute)的语法如下: [attr

浅析python中的类变量和对象变量

刚学python,学到了有关于类和对象的地方.对一个概念有点模糊,后来通过实践编码找到一定规律 在python中 class test(object): id=2 name='tt' list=['tt','dd'] def change(self,newA,new_id): self.id=new_id self.age=newA return self.age t1 = test() t1.change(21, 3) print t1.id #3 t2 = test() t2.age = 2

浅析python中_name_='_main_'

刚接触到python时,对代码中的_name_='_main_'比较疑惑,本文对其的讲解借鉴了其他博客讲述(见参考资料),希望和大家共同学习. Make a script both importable and executable 首先先看一个例子 1 #module.py 2 def main(): 3 print "we are in %s"%__name__ 4 if __name__ == '__main__': 5 main() 在这段函数中,定义main函数,当py文件被

C#中的Attribute属性

在C#中,attribute是作为一种程序源代码的元素修饰符存在的,因为有的时候我们需要给自己的代码添加一些描述性的说明信息.当这些我们不愿意用注释或内部代码用来描述的信息,被作为attribute代码而编译的话,编译器会将它们生成到metadata中去. 同时,attribute也是一种object. 1 [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method |  2 AttributeTargets.ReturnVa

浅析python 中__name__ = '__main__' 的作用

很多新手刚开始学习python的时候经常会看到python 中__name__ = \'__main__\' 这样的代码,可能很多新手一开始学习的时候都比较疑惑,python 中__name__ = '__main__' 的作用,到底干嘛的? 有句话经典的概括了这段代码的意义: "Make a script both importable and executable" 意思就是说让你写的脚本模块既可以导入到别的模块中用,另外该模块自己也可执行. __name__ 是当前模块名,当模块

从源码中浅析Android中如何利用attrs和styles定义控件

一直有个问题就是,Android中是如何通过布局文件,就能实现控件效果的不同呢?比如在布局文件中,我设置了一个TextView,给它设置了textColor,它就能够改变这个TextView的文本的颜色.这是如何做到的呢?我们分3个部分来看这个问题1.attrs.xml  2.styles.xml  3.看组件的源码. 1.attrs.xml: 我们知道Android的源码中有attrs.xml这个文件,这个文件实际上定义了所有的控件的属性,就是我们在布局文件中设置的各类属性 你可以找到attr

浅析Java中的final关键字(转)

浅析Java中的final关键字 谈到final关键字,想必很多人都不陌生,在使用匿名内部类的时候可能会经常用到final关键字.另外,Java中的String类就是一个final类,那么今天我们就来了解final这个关键字的用法.下面是本文的目录大纲: 一.final关键字的基本用法 二.深入理解final关键字 若有不正之处,请多多谅解并欢迎指正. 请尊重作者劳动成果,转载请标明原文链接: http://www.cnblogs.com/dolphin0520/p/3736238.html 一

浅析Java中的访问权限控制

浅析Java中的访问权限控制 今天我们来一起了解一下Java语言中的访问权限控制.在讨论访问权限控制之前,先来讨论一下为何需要访问权限控制.考虑两个场景: 场景1:工程师A编写了一个类ClassA,但是工程师A并不希望ClassA被该应用中其他所用的类都访问到,那么该如何处理? 场景2:如果工程师A编写了一个类ClassA,其中有两个方法fun1.fun2,工程师只想让fun1对外可见,也就是说,如果别的工程师来调用ClassA,只可以调用方法fun1,那么该怎么处理? 此时,访问权限控制便可以