【c#教程】C# 特性(Attribute)

C# 特性(Attribute)

特性(attribute)是用于在运行时传递程序中各种元素(比如类、方法、结构、枚举、组件等)的行为信息的声明性标签。您可以通过使用特性向程序添加声明性信息。一个声明性标签是通过放置在它所应用的元素前面的方括号([ ])来描述的。

特性(Attribute)用于添加元数据,如编译器指令和注释、描述、方法、类等其他信息。.Net 框架提供了两种类型的特性:预定义特性和自定义特性。

规定特性(Attribute)

规定特性(Attribute)的语法如下:

[attribute(positional_parameters, name_parameter = value, ...)]element

登录后复制

特性(Attribute)的名称和值是在方括号内规定的,放置在它所应用的元素之前。positional_parameters 规定必需的信息,name_parameter 规定可选的信息。

预定义特性(Attribute)

.Net 框架提供了三种预定义特性:

AttributeUsage

Conditional

Obsolete

AttributeUsage

预定义特性 AttributeUsage 描述了如何使用一个自定义特性类。它规定了特性可应用到的项目的类型。

规定该特性的语法如下:

[AttributeUsage(   validon,   AllowMultiple=allowmultiple,   Inherited=inherited)]

登录后复制

其中:

参数 validon 规定特性可被放置的语言元素。它是枚举器 AttributeTargets 的值的组合。默认值是 AttributeTargets.All。

参数 allowmultiple(可选的)为该特性的 AllowMultiple 属性(property)提供一个布尔值。如果为 true,则该特性是多用的。默认值是 false(单用的)。

参数 inherited(可选的)为该特性的 Inherited 属性(property)提供一个布尔值。如果为 true,则该特性可被派生类继承。默认值是 false(不被继承)。

例如:

[AttributeUsage(AttributeTargets.Class |AttributeTargets.Constructor |AttributeTargets.Feild |AttributeTargets.Method |AttributeTargets.Property, AllowMultiple = true)]

登录后复制

Conditional

这个预定义特性标记了一个条件方法,其执行依赖于它顶的预处理标识符。

它会引起方法调用的条件编译,取决于指定的值,比如 Debug 或 Trace。例如,当调试代码时显示变量的值。

规定该特性的语法如下:

[Conditional(   conditionalSymbol)]

登录后复制

例如:

[Conditional("DEBUG")]

登录后复制

下面的实例演示了该特性:

#define DEBUGusing System;using System.Diagnostics;public class Myclass{    [Conditional("DEBUG")]    public static void Message(string msg)    {        Console.WriteLine(msg);    }}class Test{    static void function1()    {        Myclass.Message("In Function 1.");        function2();    }    static void function2()    {        Myclass.Message("In Function 2.");    }    public static void Main()    {        Myclass.Message("In Main function.");        function1();        Console.ReadKey();    }}

登录后复制

当上面的代码被编译和执行时,它会产生下列结果:

In Main functionIn Function 1In Function 2

登录后复制

Obsolete

这个预定义特性标记了不应被使用的程序实体。它可以让您通知编译器丢弃某个特定的目标元素。例如,当一个新方法被用在一个类中,但是您仍然想要保持类中的旧方法,您可以通过显示一个应该使用新方法,而不是旧方法的消息,来把它标记为 obsolete(过时的)。

规定该特性的语法如下:

[Obsolete(   message)][Obsolete(   message,   iserror)]

登录后复制

其中:

参数 message,是一个字符串,描述项目为什么过时的原因以及该替代使用什么。

参数 iserror,是一个布尔值。如果该值为 true,编译器应把该项目的使用当作一个错误。默认值是 false(编译器生成一个警告)。

下面的实例演示了该特性:

using System;public class MyClass{   [Obsolete("Don't use OldMethod, use NewMethod instead", true)]   static void OldMethod()   {       Console.WriteLine("It is the old method");   }   static void NewMethod()   {       Console.WriteLine("It is the new method");    }   public static void Main()   {      OldMethod();   }}

登录后复制

当您尝试编译该程序时,编译器会给出一个错误消息说明:

 Don't use OldMethod, use NewMethod instead

登录后复制

创建自定义特性(Attribute)

.Net 框架允许创建自定义特性,用于存储声明性的信息,且可在运行时被检索。该信息根据设计标准和应用程序需要,可与任何目标元素相关。

创建并使用自定义特性包含四个步骤:

声明自定义特性

构建自定义特性

在目标程序元素上应用自定义特性

通过反射访问特性

最后一个步骤包含编写一个简单的程序来读取元数据以便查找各种符号。元数据是用于描述其他数据的数据和信息。该程序应使用反射来在运行时访问特性。我们将在下一章详细讨论这点。

声明自定义特性

一个新的自定义特性应派生自 System.Attribute 类。例如:

// 一个自定义特性 BugFix 被赋给类及其成员[AttributeUsage(AttributeTargets.Class |AttributeTargets.Constructor |AttributeTargets.Field |AttributeTargets.Method |AttributeTargets.Property,AllowMultiple = true)]public class DeBugInfo : System.Attribute

登录后复制

在上面的代码中,我们已经声明了一个名为 DeBugInfo 的自定义特性。

构建自定义特性

让我们构建一个名为 DeBugInfo 的自定义特性,该特性将存储调试程序获得的信息。它存储下面的信息:

bug 的代码编号

辨认该 bug 的开发人员名字

最后一次审查该代码的日期

一个存储了开发人员标记的字符串消息

我们的 DeBugInfo 类将带有三个用于存储前三个信息的私有属性(property)和一个用于存储消息的公有属性(property)。所以 bug 编号、开发人员名字和审查日期将是 DeBugInfo 类的必需的定位( positional)参数,消息将是一个可选的命名(named)参数。

每个特性必须至少有一个构造函数。必需的定位( positional)参数应通过构造函数传递。下面的代码演示了 DeBugInfo 类:

// 一个自定义特性 BugFix 被赋给类及其成员[AttributeUsage(AttributeTargets.Class |AttributeTargets.Constructor |AttributeTargets.Field |AttributeTargets.Method |AttributeTargets.Property,AllowMultiple = true)]public class DeBugInfo : System.Attribute{  private int bugNo;  private string developer;  private string lastReview;  public string message;  public DeBugInfo(int bg, string dev, string d)  {      this.bugNo = bg;      this.developer = dev;      this.lastReview = d;  }  public int BugNo  {      get      {          return bugNo;      }  }  public string Developer  {      get      {          return developer;      }  }  public string LastReview  {      get      {          return lastReview;      }  }  public string Message  {      get      {          return message;      }      set      {          message = value;      }  }}

登录后复制

应用自定义特性

通过把特性放置在紧接着它的目标之前,来应用该特性:

[DeBugInfo(45, "Zara Ali", "12/8/2012", Message = "Return type mismatch")][DeBugInfo(49, "Nuha Ali", "10/10/2012", Message = "Unused variable")]class Rectangle{  // 成员变量  protected double length;  protected double width;  public Rectangle(double l, double w)  {      length = l;      width = w;  }  [DeBugInfo(55, "Zara Ali", "19/10/2012",  Message = "Return type mismatch")]  public double GetArea()  {      return length * width;  }  [DeBugInfo(56, "Zara Ali", "19/10/2012")]  public void Display()  {      Console.WriteLine("Length: {0}", length);      Console.WriteLine("Width: {0}", width);      Console.WriteLine("Area: {0}", GetArea());  }}

登录后复制

 以上就是【c#教程】C# 特性(Attribute)的内容,更多相关内容请关注PHP中文网(www.php.cn)!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至253000106@qq.com举报,一经查实,本站将立刻删除。

发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/2553683.html

(0)
上一篇 2025年3月6日 06:47:52
下一篇 2025年3月6日 06:47:57

AD推荐 黄金广告位招租... 更多推荐

相关推荐

  • 【c#教程】C# 文件的输入与输出

    C# 文件的输入与输出 一个 文件 是一个存储在磁盘中带有指定名称和目录路径的数据集合。当打开文件进行读写时,它变成一个 流。 从根本上说,流是通过通信路径传递的字节序列。有两个主要的流:输入流 和 输出流。输入流用于从文件读取数据(读操作…

    编程技术 2025年3月6日
    200
  • 【c#教程】C# 异常处理

    C# 异常处理 异常是在程序执行期间出现的问题。c# 中的异常是对程序运行时出现的特殊情况的一种响应,比如尝试除以零。 异常提供了一种把程序控制权从某个部分转移到另一个部分的方式。C# 异常处理时建立在四个关键词之上的:try、catch、…

    编程技术 2025年3月6日
    200
  • 【c#教程】C# 正则表达式

    C# 正则表达式 正则表达式 是一种匹配输入文本的模式。.net 框架提供了允许这种匹配的正则表达式引擎。模式由一个或多个字符、运算符和结构组成。 定义正则表达式 下面列出了用于定义正则表达式的各种类别的字符、运算符和结构。 字符转义 字符…

    编程技术 2025年3月6日
    200
  • 【c#教程】C# 预处理器指令

    C# 预处理器指令 预处理器指令指导编译器在实际编译开始之前对信息进行预处理。 所有的预处理器指令都是以 # 开始。且在一行上,只有空白字符可以出现在预处理器指令之前。预处理器指令不是语句,所以它们不以分号(;)结束。 C# 编译器没有一个…

    编程技术 2025年3月6日
    200
  • 【c#教程】C# 命名空间(Namespace)

    C# 命名空间(Namespace) 命名空间的设计目的是为了提供一种让一组名称与其他名称分隔开的方式。在一个命名空间中声明的类的名称与另一个命名空间中声明的相同的类的名称不冲突。 定义命名空间 命名空间的定义是以关键字 namespace…

    编程技术 2025年3月6日
    200
  • 【c#教程】C# 接口(Interface)

    C# 接口(Interface) 接口定义了所有类继承接口时应遵循的语法合同。接口定义了语法合同 “是什么” 部分,派生类定义了语法合同 “怎么做” 部分。 接口定义了属性、方法和事件,这些都…

    编程技术 2025年3月6日
    200
  • 【c#教程】C# 运算符重载

    C# 运算符重载 您可以重定义或重载 c# 中内置的运算符。因此,程序员也可以使用用户自定义类型的运算符。重载运算符是具有特殊名称的函数,是通过关键字 operator 后跟运算符的符号来定义的。与其他函数一样,重载运算符有返回类型和参数列…

    编程技术 2025年3月6日
    200
  • 【c#教程】C# 多态性

    C# 多态性 多态性意味着有多重形式。在面向对象编程范式中,多态性往往表现为”一个接口,多个功能”。 多态性可以是静态的或动态的。在静态多态性中,函数的响应是在编译时发生的。在动态多态性中,函数的响应是在运行时发生的…

    编程技术 2025年3月6日
    200
  • 【c#教程】C# 继承

    C# 继承 继承是面向对象程序设计中最重要的概念之一。继承允许我们根据一个类来定义另一个类来定义一个类,这使得创建和维护应用程序变得更容易。同时也有利于重用代码和节省开发时间。 当创建一个类时,程序员不需要完全重新编写新的数据成员和成员函数…

    编程技术 2025年3月6日
    200
  • 【c#教程】C# 程序结构

    C# 程序结构 在我们学习 c# 编程语言的基础构件块之前,让我们先看一下 c# 的最小的程序结构,以便作为接下来章节的参考。 C# Hello World 实例 一个 C# 程序主要包括以下部分: 命名空间声明(Namespace dec…

    编程技术 2025年3月6日
    200

发表回复

登录后才能评论