zoukankan      html  css  js  c++  java
  • 浅析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; }
        }

    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 该命名参数指定所指示的属性能否由派生类和重写成员继承。

    转载请说明出处,谢谢![hyddd(http://www.cnblogs.com/hyddd/)]

    四.参考资料

    【1】Msdn

    【2】《你必须知道的.NET之特性和属性》,博主严重推荐!

    【3】《Attribute在.net编程中的应用》系列文章

    作者:hyddd
    出处:http://www.cnblogs.com/hyddd/
    本文版权归作者所有,欢迎转载,演绎或用于商业目的,但是必须说明本文出处(包含链接)。

  • 相关阅读:
    小小知识点(二)——如何修改win10 的C盘中用户下的文件夹名称
    Day15 Python基础之logging模块(十三)
    Day14 Python基础之os/sys/hashlib模块(十二)
    Day13 Python基础之time/datetime/random模块一(十一)
    Day12 Python基础之生成器、迭代器(高级函数)(十)
    Day11 Python基础之装饰器(高级函数)(九)
    火狐HACK
    javascript操作cookie
    <!DOCTYPE>标签的定义与用法
    前端性能优化
  • 原文地址:https://www.cnblogs.com/lsgsanxiao/p/4568151.html
Copyright © 2011-2022 走看看