`

【转】C# 特性(Attribute)入门

阅读更多

绪论

特性(Attributes)是一种崭新的声明性信息。我们不仅可以通过特性来定义设计层面的信息(例如help file, URL for documentation)以及运行时(run-time)信息(例如使XMLclass相联系),而且我们还可以利用特性建立自描述(self-describing)组件。在这篇教程中,我们将会看到如何建立和添加特性到各种程序实体以及如何在运行时环境中获取特性信息。

定义

正如MSDN中所描述的那样-----

   “特性是被指定给某一声明的一则附加的声明性信息。”

使用预定义(Pre-defined)特性

C#中,有一个小的预定义特性集合。在学习如何建立我们自己的定制特性(custom attributes)之前,我们先来看看在我们的代码中如何使用预定义特性。

using System;
publicclass AnyClass 
{
    [Obsolete("Don''''t use Old method, use New method", true)]
    staticvoid Old( ) { }
   
    staticvoid New( ) { }
   
    publicstaticvoid Main( ) 
    {
        Old( );
    }
}

我们先来看一下上面这个例子,在这个例子中我们使用了Obsolete特性,它标记了一个不应该再被使用的程序实体。第一个参数是一个字符串,它解释了为什么该实体是过时的以及应该用什么实体来代替它。实际上,你可以在这里写任何文本。第二个参数告诉编译器应该把使用这个过时的程序实体当作一种错误。它的默认值是false,也就是说编译器对此会产生一个警告。

当我们尝试编译上面这段程序的时候,我们将会得到一个错误:

AnyClass.Old()'''' is obsolete: ''''Don''''t use Old method, use New method''''

开发定制特性(custom attributes

现在让我们来看看如何开发我们自己的特性。

首先我们要从System.Attribute派生出我们自己的特性类(一个从System.Attribute抽象类继承而来的类,不管是直接还是间接继承,都会成为一个特性类。特性类的声明定义了一种可以被放置在声明之上新的特性)。

using System;
publicclass HelpAttribute : Attribute
{
}

不管你是否相信,我们已经建立了一个定制特性,现在我们可以用它来装饰现有的类就好像上面我们使用Obsolete attribute一样。

[Help()]
publicclass AnyClass
{
}

注意:对一个特性类名使用Attribute后缀是一个惯例。然而,当我们把特性添加到一个程序实体,是否包括Attribute后缀是我们的自由。编译器会首先在System.Attribute的派生类中查找被添加的特性类。如果没有找到,那么编译器会添加Attribute后缀继续查找。

到目前为止,这个特性还没有起到什么作用。下面我们来添加些东西给它使它更有用些。

using System;
publicclass HelpAttribute : Attribute
{
    public HelpAttribute(String Descrition_in)
    {
        this.description = Description_in;
    }
    protected String description;
    public String Description 
    {
        get
        {
            returnthis.description;
                 
        }            
    }    
}
[Help("this is a do-nothing class")]
publicclass AnyClass
{
}





定义或控制特性的使用

AttributeUsage类是另外一个预定义特性类,它帮助我们控制我们自己的定制特性的使用。它描述了一个定制特性如和被使用。

AttributeUsage有三个属性,我们可以把它放置在定制属性前面。第一个属性是:

ValidOn

通过这个属性,我们能够定义定制特性应该在何种程序实体前放置。一个属性可以被放置的所有程序实体在AttributeTargets enumerator中列出。通过OR操作我们可以把若干个AttributeTargets值组合起来。

AllowMultiple

这个属性标记了我们的定制特性能否被重复放置在同一个程序实体前多次。

Inherited

我们可以使用这个属性来控制定制特性的继承规则。它标记了我们的特性能否被继承。

下面让我们来做一些实际的东西。我们将会在刚才的Help特性前放置AttributeUsage特性以期待在它的帮助下控制Help特性的使用。

using System;[AttributeUsage(AttributeTargets.Class), AllowMultiple = false,  Inherited = false ]publicclass HelpAttribute : Attribute{    public HelpAttribute(String Description_in)    {        this.description = Description_in;    }    protected String description;    public String Description    {        get        {            returnthis.description;        }                }    }

先让我们来看一下AttributeTargets.Class。它规定了Help特性只能被放在class的前面。这也就意味着下面的代码将会产生错误:

[Help("this is a do-nothing class")]publicclass AnyClass{    [Help("this is a do-nothing method")]    //error    publicvoid AnyMethod()    {    }}

编译器报告错误如下:

AnyClass.cs: Attribute ''''Help'''' is not valid on this declaration type.

It is valid on ''''class'''' declarations only.

我们可以使用AttributeTargets.All来允许Help特性被放置在任何程序实体前。可能的值是:

  • Assembly, 
  • Module, 
  • Class, 
  • Struct, 
  • Enum, 
  • Constructor, 
  • Method, 
  • Property, 
  • Field,
  • Event, 
  • Interface, 
  • Parameter, 
  • Delegate, 
  • All = Assembly | Module | Class | Struct | Enum | Constructor | Method | Property | Field | Event | Interface | Parameter | Delegate,
  • ClassMembers = Class | Struct | Enum | Constructor | Method | Property | Field | Event | Delegate | Interface )

下面考虑一下AllowMultiple = false。它规定了特性不能被重复放置多次。

[Help("this is a do-nothing class")][Help("it contains a do-nothing method")]publicclass AnyClass{    [Help("this is a do-nothing method")]        //error    publicvoid AnyMethod()    {    }}

它产生了一个编译期错误。

AnyClass.cs: Duplicate ''''Help'''' attribute

Ok,现在我们来讨论一下最后的这个属性。Inherited, 表明当特性被放置在一个基类上时,它能否被派生类所继承。

[Help("BaseClass")] publicclass Base{} publicclass Derive : Base{}

这里会有四种可能的组合:

  • [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false
  • [AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = false
  • [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true
  • [AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true

第一种情况:

如果我们查询(Query)(稍后我们会看到如何在运行期查询一个类的特性)Derive类,我们将会发现Help特性并不存在,因为inherited属性被设置为false

第二种情况:

和第一种情况相同,因为inherited也被设置为false

 

第三种情况:

为了解释第三种和第四种情况,我们先来给派生类添加点代码:

[Help("BaseClass")] publicclass Base{}[Help("DeriveClass")] publicclass Derive : Base{}

现在我们来查询一下Help特性,我们只能得到派生类的属性,因为inherited被设置为true,但是AllowMultiple却被设置为false。因此基类的Help特性被派生类Help特性覆盖了。

第四种情况:

在这里,我们将会发现派生类既有基类的Help特性,也有自己的Help特性,因为AllowMultiple被设置为true


在上面的例子中,我们给HelpAttribute特性类添加了一个属性并且在后续的部分中我们会在运行时环境中查寻它。

分享到:
评论

相关推荐

    C#从入门到精通、c#高级编程

    3. **.NET框架**:深入.NET框架,包括反射、元数据、特性(Attribute)等。 4. **Entity Framework**:C#的ORM框架,用于数据库操作和对象关系映射。 5. **ASP.NET**:如果涵盖此部分,将介绍如何使用C#开发Web...

    C#反射特性 基础入门

    C#反射特性 基础入门,对新手绝对有帮助。 其中得到小伙伴赵勇的指导和参照这篇文章: http://www.cnblogs.com/jyk/archive/2010/08/06/1793668.html

    入门c#指南.pdf

    《入门c#指南.pdf》是一份详尽的C#编程语言学习资源,由Microsoft官方提供,覆盖了C#编程语言的各个方面,包括基础概念、编程指南、最新版本的新特性以及丰富的编程示例。该指南适合新手和有经验的开发者,为他们...

    C# XML入门经典 —— C#编程人员必备的XML技能

    对于C#编程人员来说,掌握XML的基本操作和高级特性是至关重要的。下面我们将深入探讨C#中与XML相关的知识。 一、XML基础 1. XML结构:XML文档由元素(Element)、属性(Attribute)、文本(Text)、注释(Comment)...

    入门-C#指南中文.pdf

    其中还包括了关于使用特性(Attribute)来增强代码功能的指导,这是C#语言特有的强大特性之一。 .NET Compiler Platform SDK(也称为Roslyn API)的部分为那些希望深入编译器工作原理的读者提供了入门知识。这份...

    DOTNET-C#基础快速入门教程-全网最简单

    **C#基础** C#是一种面向对象的编程语言,由微软公司开发,主要用于构建Windows应用程序...以上就是C#基础快速入门的关键知识点,这些概念构成了C#编程的基础,学习并掌握它们是进一步学习高级特性和开发技能的前提。

    c#从入门到精通和c#完全手册

    13. AOP(面向切面编程):通过特性(Attribute)实现代码的解耦和模块化。 14. LINQ(Language Integrated Query):在C#中内置的查询语言,使得数据查询更加直观和简洁。 15. 异步编程:利用async/await关键字进行...

    c#入门经典第六版代码

    《C#入门经典》第六版是针对初学者的权威指南,旨在帮助读者掌握C#编程的基础知识和高级特性。这本书通过丰富的实例和练习,使学习者能够快速理解和应用C#语言。 在Visual Studio 2012环境下编写和运行C#代码,...

    C#学习(微软原版2021).pdf

    特性(Attribute)是C#的一种用于声明性编程的机制,允许开发者在代码中添加元数据。通过特性,我们可以为方法、类、字段等添加额外的信息,这些信息可以在运行时通过反射来读取和使用。 ### 编译器*** *** ...

    c#入门教程

    ### C#入门教程知识点详解 #### 一、C#与.NET的关系 C#是一种现代的、面向对象的编程语言,由微软开发,主要用于.NET环境下的应用程序开发。虽然C#是独立于.NET的语言,但它编写的代码总是运行在.NET Framework或...

    C#入门经典(VS2008)英文版

    ### C# 入门经典(VS2008)知识点概览 #### 一、C#语言基础 **1.1 引入C#** - **C#简介**:本书第一章介绍了C#语言的基本概念和发展历程,解释了为什么C#会成为一种流行的编程语言,并概述了它与.NET框架的关系。...

    C#经典教程

    - **面向对象特性**:C#是一种纯粹的面向对象语言,支持封装、继承和多态等核心概念,并引入了如特性(Attribute)、属性(Property)、委托(Delegate)等高级特性,提高了代码的复用性和可维护性。 - **Web开发...

    Effective C#

    13. **了解特性(Attribute)**:特性是元数据的一部分,允许向编译器或运行时提供额外信息,如`[Serializable]`或`[OperationContract]`。 14. **利用扩展方法**:扩展方法允许你在不改变原有类的情况下为其添加新...

    c#200个编程实例

    每个实例都会结合具体的场景,引导学习者逐步实现功能,通过实践加深对C#特性的理解。此外,解压缩后的文件名“200个编程实例”可能包含多个源代码文件,每个文件对应一个实例,学习者可以逐个研究并运行这些代码,...

    CSharp调用WindowsAPI入门_C#_windowsapi_

    2. **DllImport Attribute**:这是C#中用于指定外部方法声明的特性,用于告诉编译器该方法是在非托管代码(如DLL)中定义的。 3. **Structures and Marshaling**:由于C#和Windows API的数据类型不完全匹配,我们...

    c#汇总,包括asp.net xml c#基础知识

    5. 继承与多态:C#支持单一继承,一个类可以继承自另一个类,从而获取其特性。多态是通过抽象类(Abstract Class)和接口(Interface)来实现的。 6. 异常处理:C#使用try-catch-finally语句来捕获和处理运行时错误...

    C#语言规范.

    C#的入门程序通常是输出“Hello World”到控制台。这可以通过调用Console类的WriteLine静态方法实现。 1.2 程序结构 C#程序的结构包含命名空间(Namespace)、类型(Type)、成员(Member)和程序块(Block)。命名...

    Thinking In C#(Prentice Hall)

    本书不仅适合初学者入门,也适合有经验的开发者进一步掌握C#的高级特性。 #### 重要知识点概览 1. **面向对象编程基础** - 对象的概念与特点 - 接口和服务提供 - 隐藏实现细节的重要性 - 实现重用的方式 2. *...

    XML轻松入门到精通

    在"XML轻松入门到精通"的CHM文件中,读者将逐步学习这些概念,从基本的XML语法开始,逐渐深入到高级特性和应用。CHM文件是一种编译后的HTML帮助文档,便于查阅和学习,通常包含目录、索引和搜索功能,便于快速定位所...

Global site tag (gtag.js) - Google Analytics