English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Caratteristica di C# (Attribute)

Caratteristica (Attribute)Sono etichette dichiarative utilizzate per trasmettere informazioni sul comportamento degli elementi vari (ad esempio classi, metodi, strutture, enum, componenti) in tempo di esecuzione. Puoi aggiungere informazioni dichiarative al programma utilizzando le caratteristiche. Un etichetta dichiarativa è descritta da parentesi quadre collocate davanti all'elemento a cui si applica.

La caratteristica (Attribute) viene utilizzata per aggiungere metadati come istruzioni del compilatore, commenti, descrizioni, metodi, classi e altri informazioni. La framework .Net fornisce due tipi di caratteristiche:PredefiniteE caratteristichePersonalizzataCaratteristica.

Caratteristica (Attribute)

La sintassi della caratteristica (Attribute) è la seguente:

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

Il nome e il valore della caratteristica (Attribute) sono specificati tra parentesi quadre e collocati prima dell'elemento a cui si applica. positional_parameters specifica le informazioni necessarie, name_parameter specifica le informazioni opzionali.

Caratteristica predefinita(Attribute)

La framework .Net fornisce tre tipi di caratteristiche predefinite:

  • AttributeUsage

  • Conditional

  • Obsoleto

AttributeUsage

Caratteristiche predefinite AttributeUsage Descrive come utilizzare una classe di caratteristica personalizzata. Specifica il tipo di progetto a cui può essere applicata la caratteristica.

La sintassi di questa caratteristica predefinita è la seguente:

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

dove:

  • Il parametro validon specifica gli elementi linguistici ai quali può essere applicata la caratteristica. È un enumeratore AttributeTargets la combinazione di valori di AttributeTargets.All.

  • parametro allowmultiple(Opzionale) Per l'attributo AllowMultiple L'attributo (property) fornisce un valore booleano. Se impostato su true, la funzionalità è multiplo. Il valore predefinito è false (singolo).

  • parametro inherited(Opzionale) Per l'attributo Inherited L'attributo (property) fornisce un valore booleano. Se impostato su true, la funzionalità può essere ereditata dalla sottoclasse. Il valore predefinito è false (non ereditabile).

Ad esempio:

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

Conditional

Questa funzionalità predefinita segna un metodo condizionale, la cui esecuzione dipende dal simbolo di preprocessing specificato.

causerà la compilazione condizionale delle chiamate di metodo, a seconda del valore specificato, come Debug o Trace. Ad esempio, mostrare i valori delle variabili durante la debuggaione del codice.

La sintassi di questa caratteristica predefinita è la seguente:

[Conditional(
   simboloCondicionale
)]

Ad esempio:

[Conditional("DEBUG")]

Esempio seguente dimostra questa caratteristica:

#define DEBUG
using 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 funzione principale.");
        function1();
        Console.ReadKey();
    {}
{}

Quando il codice sopra viene compilato ed eseguito, produrrà i seguenti risultati:

In funzione principale
In Function 1
In Function 2

Obsoleto

Questa caratteristica predefinita segnala elementi del programma che non dovrebbero essere utilizzati. Permette di notificare al compilatore di disattenersi da un elemento specifico. Ad esempio, quando un nuovo metodo viene utilizzato in una classe ma si desidera mantenere il metodo vecchio nella classe, è possibile segnalarlo come obsolete (obsoleto) mostrando un messaggio che dovrebbe utilizzare il nuovo metodo invece del vecchio.

La sintassi di questa caratteristica predefinita è la seguente:

[Obsoleto(
   message
)]
[Obsoleto(
   message,
   iserror
)]

dove:

  • parametro messageè una stringa che descrive il motivo per cui l'elemento è obsoleto e cosa utilizzare al suo posto.

  • parametro iserrorè un valore booleano. Se questo valore è true, il compilatore dovrebbe considerare l'uso di questo elemento come un errore. Il valore predefinito è false (il compilatore genera un avviso).

Esempio seguente dimostra questa caratteristica:

using System;
public class MyClass
{
   [Obsoleto("Non utilizzare OldMethod, utilizzare NewMethod invece", 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;
      {}
  {}
{}

Applicazione dell'attributo personalizzato

Per applicare l'attributo, posizionalo davanti all'oggetto a cui si desidera applicarlo:

[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("Lunghezza: {0}", length);
      Console.WriteLine("Larghezza: {0}", width);
      Console.WriteLine("Area: {0}", GetArea());
  {}
{}

Nel prossimo capitolo, utilizzeremo l'oggetto della classe Reflection per recuperare queste informazioni.