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

C# 基础教程

C# 高级教程

C#面向对象(OOP)

Атрибуты (Attribute) в C#

характеристика (Attribute)являются декларативными метками, которые передают информацию о поведении различных элементов программы (например, классы, методы, структуры, перечисления, компоненты и т.д.) в runtime. Вы можете добавить декларативную информацию в программу с помощью характеристик. Декларативная метка описывается放置ением в квадратных скобках перед элементом, на котором она применяется.

характеристика (Attribute) используется для добавления метаданных, таких как инструкции компилятора и комментарии, описание, методы, классы и другая информация. .Net фреймворк предоставляет два типа характеристик:предварительно определеннаяхарактеристика ипользовательскаяхарактеристика.

характеристика (Attribute)

синтаксис характеристики (Attribute) указан следующим образом:

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

имя и значение характеристики (Attribute) указываются в квадратных скобках, и они помещаются перед элементом, на котором они применяются. positional_parameters определяет обязательную информацию, name_parameter определяет дополнительную информацию.

предварительно определенная характеристика(Attribute)

.Net фреймворк предоставляет три предварительно определенные характеристики:

  • AttributeUsage

  • Conditional

  • Отказано в поддержке

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.Field |
AttributeTargets.Method |
AttributeTargets.Property, 
AllowMultiple = true)]

Conditional

Эта предварительно определенная функция помечает метод условия, выполнение которого зависит от указанного идентификатора предварительной обработки.

это会引起 метод вызова условного компиляции, в зависимости от указанного значения, например Debug или Trace. Например, когда отладочный код отображает значения переменных.

Синтаксис этой характеристики следующий:

[Conditional(
   conditionalSymbol
)]

Например:

[Conditional("DEBUG")]

Ниже приведен пример использования этой характеристики:

#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("В функции 1.");
        function2();
    }
    static void function2()
    {
        Myclass.Message("В функции 2.");
    }
    public static void Main()
    {
        Myclass.Message("В главной функции.");
        function1();
        Console.ReadKey();
    }
}

Когда вышеуказанный код компилируется и выполняется, он produces следующие результаты:

В главной функции
В функции 1
В функции 2

Отказано в поддержке

Эта предопределенная характеристика указывает на программные объекты, которые не должны использоваться. Она позволяет уведомить компилятор о том, что определенный целевой элемент следует弃норвать. Например, когда новый метод используется в классе, но вы все еще хотите поддерживать старый метод в этом классе, вы можете отметить его как устаревший (отказано в поддержке), показав сообщение о том, что следует использовать новый метод, а не старый.

Синтаксис этой характеристики следующий:

[Отказано в поддержке(
   message
)]
[Отказано в поддержке(
   message,
   iserror
)]

в частности:

  • параметр messageявляется строкой, описывающей, почему элемент стал устаревшим и что следует использовать вместо него.

  • параметр iserrorявляется булевой величиной. Если это значение равно true, компилятор должен рассматривать использование этого элемента как ошибку. Значение по умолчанию false (генерируется предупреждение компилятором).

Ниже приведен пример использования этой характеристики:

using System;
public class MyClass
{
   [Отказано в поддержке("Не используйте OldMethod, вместо этого используйте NewMethod", 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
  {
      получить
      {
          return bugNo;
      }
  }
  public string Developer
  {
      получить
      {
          return developer;
      }
  }
  public string LastReview
  {
      получить
      {
          return lastReview;
      }
  }
  public string Message
  {
      получить
      {
          return message;
      }
      установить
      {
          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("Длина: {0}", length);
      Console.WriteLine("Ширина: {0}", width);
      Console.WriteLine("Площадь: {0}", GetArea());
  }
}

В следующей главе мы будем использовать объект класса Reflection для извлечения этой информации.