Csharp 简明教程

C

attribute 是一种声明性标记,用于向运行时传达各种元素(比如程序中的类、方法、结构、枚举符、程序集等)的行为的信息。你可以使用一个属性向程序添加声明性信息。一个声明性标记由中括号([])描绘,位于其所属元素的上方。

An attribute is a declarative tag that is used to convey information to runtime about the behaviors of various elements like classes, methods, structures, enumerators, assemblies etc. in your program. You can add declarative information to a program by using an attribute. A declarative tag is depicted by square ([ ]) brackets placed above the element it is used for.

属性用于向一个程序添加元数据,如编译器指令以及其他信息,如注释、描述、方法和类。.Net Framework 提供两种类型的属性:预定义的属性和自定义的属性。

Attributes are used for adding metadata, such as compiler instruction and other information such as comments, description, methods and classes to a program. The .Net Framework provides two types of attributes: the pre-defined attributes and custom built attributes.

Specifying an Attribute

指定一个属性的语法如下:

Syntax for specifying an attribute is as follows −

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

在属性要应用于元素之前,该属性的名称和值在中括号中指定。位置参数指定必要的信息,名称参数指定可选信息。

Name of the attribute and its values are specified within the square brackets, before the element to which the attribute is applied. Positional parameters specify the essential information and the name parameters specify the optional information.

Predefined Attributes

Net Framework 提供三个预定义的属性:

The .Net Framework provides three pre-defined attributes −

  1. AttributeUsage

  2. Conditional

  3. Obsolete

AttributeUsage

预定义的属性 AttributeUsage 描述如何使用一个自定义属性类。它指定可以将属性应用于哪些类型的项。

The pre-defined attribute AttributeUsage describes how a custom attribute class can be used. It specifies the types of items to which the attribute can be applied.

指定此属性的语法如下:

Syntax for specifying this attribute is as follows −

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

其中,

Where,

  1. The parameter validon specifies the language elements on which the attribute can be placed. It is a combination of the value of an enumerator AttributeTargets. The default value is AttributeTargets.All.

  2. The parameter allowmultiple (optional) provides value for the AllowMultiple property of this attribute, a Boolean value. If this is true, the attribute is multiuse. The default is false (single-use).

  3. The parameter inherited (optional) provides value for the Inherited property of this attribute, a Boolean value. If it is true, the attribute is inherited by derived classes. The default value is false (not inherited).

例如,

For example,

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

Conditional

此预定义属性标记了执行取决于指定预处理标识符的条件方法。

This predefined attribute marks a conditional method whose execution depends on a specified preprocessing identifier.

它会导致方法调用的条件编译,具体取决于指定的值,例如 Debug 或 * Trace*。例如,它在调试代码时显示变量的值。

It causes conditional compilation of method calls, depending on the specified value such as Debug or * Trace*. For example, it displays the values of the variables while debugging a code.

指定此属性的语法如下:

Syntax for specifying this attribute is as follows −

[Conditional(
   conditionalSymbol
)]

例如,

For example,

[Conditional("DEBUG")]

以下示例演示了该属性:

The following example demonstrates the attribute −

#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 Main function.");
      function1();
      Console.ReadKey();
   }
}

编译并执行上述代码后,将产生以下结果 −

When the above code is compiled and executed, it produces the following result −

In Main function
In Function 1
In Function 2

Obsolete

此预定义属性标记了不应使用的程序实体。它使您可以通知编译器丢弃特定目标元素。例如,当新方法正在类中使用时,如果您仍希望保留类中的旧方法,则可以通过显示消息(应使用新方法,而不是旧方法)来将其标记为过时。

This predefined attribute marks a program entity that should not be used. It enables you to inform the compiler to discard a particular target element. For example, when a new method is being used in a class and if you still want to retain the old method in the class, you may mark it as obsolete by displaying a message the new method should be used, instead of the old method.

指定此属性的语法如下:

Syntax for specifying this attribute is as follows −

[Obsolete (
   message
)]

[Obsolete (
   message,
   iserror
)]

其中,

Where,

  1. The parameter message, is a string describing the reason why the item is obsolete and what to use instead.

  2. The parameter iserror, is a Boolean value. If its value is true, the compiler should treat the use of the item as an error. Default value is false (compiler generates a warning).

以下程序演示了这一点 −

The following program demonstrates this −

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();
   }
}

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

When you try to compile the program, the compiler gives an error message stating −

 Don't use OldMethod, use NewMethod instead

Creating Custom Attributes

Net Framework 允许创建自定义属性,用于存储声明信息,且可在运行时检索。该信息可与任何目标元素相关,具体取决于设计标准和应用程序需求。

The .Net Framework allows creation of custom attributes that can be used to store declarative information and can be retrieved at run-time. This information can be related to any target element depending upon the design criteria and application need.

创建和使用自定义属性涉及四个步骤:

Creating and using custom attributes involve four steps −

  1. Declaring a custom attribute

  2. Constructing the custom attribute

  3. Apply the custom attribute on a target program element

  4. Accessing Attributes Through Reflection

最后一步涉及编写一个简单程序来遍历元数据以查找各种符号。元数据是用于描述其他数据的数据或信息。该程序应使用反射在运行时访问属性。我们将在下一章讨论这一点。

The Last step involves writing a simple program to read through the metadata to find various notations. Metadata is data about data or information used for describing other data. This program should use reflections for accessing attributes at runtime. This we will discuss in the next chapter.

Declaring a Custom Attribute

一个新的自定义属性应从 System.Attribute 类派生。例如,

A new custom attribute should is derived from the System.Attribute class. For example,

//a custom attribute BugFix to be assigned to a class and its members
[AttributeUsage(
   AttributeTargets.Class |
   AttributeTargets.Constructor |
   AttributeTargets.Field |
   AttributeTargets.Method |
   AttributeTargets.Property,
   AllowMultiple = true)]

public class DeBugInfo : System.Attribute

在前面的代码中,我们声明了一个名为 DeBugInfo 的自定义属性。

In the preceding code, we have declared a custom attribute named DeBugInfo.

Constructing the Custom Attribute

让我们构造一个名为 DeBugInfo 的自定义属性,它存储通过调试任何程序获取的信息。让它存储以下信息:

Let us construct a custom attribute named DeBugInfo, which stores the information obtained by debugging any program. Let it store the following information −

  1. The code number for the bug

  2. Name of the developer who identified the bug

  3. Date of last review of the code

  4. A string message for storing the developer’s remarks

DeBugInfo 类有三个用于存储前三个信息的私有属性和一个用于存储消息的公有属性。因此,错误编号、开发人员姓名和审查日期是 DeBugInfo 类的定位参数,消息是可选或命名参数。

The DeBugInfo class has three private properties for storing the first three information and a public property for storing the message. Hence the bug number, developer’s name, and date of review are the positional parameters of the DeBugInfo class and the message is an optional or named parameter.

每个属性都必须至少有一个构造函数。应通过构造函数传递定位参数。以下代码显示了 DeBugInfo 类 -

Each attribute must have at least one constructor. The positional parameters should be passed through the constructor. The following code shows the DeBugInfo class −

//a custom attribute BugFix to be assigned to a class and its members
[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;
      }
   }
}

Applying the Custom Attribute

通过在目标之前直接放置该属性来应用该属性 -

The attribute is applied by placing it immediately before its target −

[DeBugInfo(45, "Zara Ali", "12/8/2012", Message = "Return type mismatch")]
[DeBugInfo(49, "Nuha Ali", "10/10/2012", Message = "Unused variable")]
class Rectangle {
   //member variables
   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());
   }
}

在下一章中,我们将使用 Reflection 类对象检索属性信息。

In the next chapter, we retrieve attribute information using a Reflection class object.