文档章节

浅析C#中的Attribute

产品哥
 产品哥
发布于 2016/12/20 10:25
字数 1471
阅读 21
收藏 0

最近用到了,所以静下心来找些资料看了一下,终于把这东西搞清楚了。

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

本文转载自:http://www.cnblogs.com/hyddd/archive/2009/07/20/1526777.html

产品哥
粉丝 81
博文 161
码字总数 190936
作品 1
杭州
CTO(技术副总裁)
私信 提问
浅析浏览器插件技术---c#篇

关于软件设计人员开发浏览器插件技术都是保密的,这类的计算机学术内容是很少的,早期的程序员都是自己摸索,要走许多弯路。 从当今浏览器插件开发来看,谷歌浏览器走在前沿,谷歌内部开发者...

crossmix
2015/12/14
112
0
C#读取文件夹中的文件操作浅析

C#读取文件夹中的文件操作浅析 C#读取文件夹中的文件操作是怎么样子的呢?那么本文就向你介绍这方面的内容,希望对你有所帮助。 C#读取文件夹的操作是如何进行的呢?首先让我们来看啊可能:读...

长平狐
2013/01/06
177
0
学习C#:Attribute与Property

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

随智阔
2013/04/09
0
0
PostSharp - Thread Dispatching(GUI多线程)

在我们的桌面应用程序(不管是WinForm还是WPF)我们都必须去面对线程的dispatching。在window图形用户系统中像基于.net的WinForm或者是WPF都有一个唯一的主线程。他们是基于Win32消息循环队...

zting科技
2017/01/10
0
0
Selenium PageObjects and PageFactory

PageObject Design Pattern The PageObject design pattern models areas of a UI as objects within test code. The functionality classes (PageObjects) in this design represent a logi......

红焖鲤鱼
2016/03/24
133
0

没有更多内容

加载失败,请刷新页面

加载更多

高度可配置的 Linux 内存守护程序 Nohang!

部分功能特性 具有良好注释的配置文件,配置方面(配置中有 38 个参数) 可以将 SIGKILL 和 SIGTERM 作为发送给 victim 的信号 支持 zram(使用 mem_used_total 作为触发器) 可定制的监控强...

linuxCool
5分钟前
0
0
开源 java CMS - FreeCMS2.8 数据对象 unit

项目地址:http://www.freeteam.cn/ unit 在使用单位相关标签时,标签会封装unit供页面调用。 属性 说明 id id ismail 是否接收互动信件 name 名称 parid 父单位id isok 是否有效 ordernum 排...

freeteam
12分钟前
0
0
awk

awk awk 是一种编程语言,用于在linux/unix下对文本和数据进行处理。数据可以来自标准输入(stdin)、一个或多个文件,或其它命令的输出。它支持用户自定义函数和动态正则表达式等先进功能,是...

李超小牛子
23分钟前
0
0
扩展资源服务器解决oauth2 性能瓶颈

用户携带token 请求资源服务器 资源服务器拦截器 携带token 去认证服务器 调用tokenstore 对token 合法性校验 资源服务器拿到token,默认只会含有用户名信息 通过用户名调用userdetailsserv...

冷冷gg
55分钟前
21
0
[Git] Git整理(四) git rebase 的使用

概述 在之前总结分支相关内容时说道,合并两个分支的提交可以使用git merge,然而除了这种方式之外,还有一种方式就是使用git rebase,这两种方式的最终结果都相同,但是合并历史却不同;git...

天王盖地虎626
今天
9
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部