C# - 属性

属性是一个声明性标记,用于向运行时传递有关程序中各种元素(如类,方法,结构,枚举器,程序集等)的行为的信息.您可以使用属性将声明性信息添加到程序中.声明性标记由位于其所用元素上方的方括号([])括号描述.

属性用于添加元数据,例如编译器指令和其他信息(如注释),程序的描述,方法和类. .Net Framework提供两种类型的属性:预定义的属性和自定义构建的属性.

指定属性

指定属性的语法如下 :

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


属性的名称及其值在方括号内指定,在应用属性的元素之前.位置参数指定基本信息,名称参数指定可选信息.

预定义属性

.Net Framework提供三个预定义属性&minus ;

  • AttributeUsage

  • 条件

  • 已过时

AttributeUsage

预定义属性 AttributeUsage 描述自定义属性类如何使用.它指定了可以应用属性的项目类型.

指定此属性的语法如下 :

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


其中,

  • 参数validon指定可以放置属性的语言元素.它是枚举器 AttributeTargets 的值的组合.默认值为 AttributeTargets.All .

  • 参数 allowmultiple (可选)为此属性的 AllowMultiple 属性,一个布尔值.如果是,则属性为多用途.默认值为false(单次使用).

  • 参数inherited(可选)为此属性的 Inherited 属性提供值,一个布尔值.如果为true,则属性由派生类继承.默认值为false(不是继承).

例如,

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


条件

此预定义属性标记一个条件方法,其执行依赖于指定的预处理标识符.

它会导致方法调用的条件编译,具体取决于指定的值,例如 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("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 function
In Function 1
In Function 2


已过时

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

指定此属性的语法如下 :

[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


创建自定义属性

.Net Framework允许创建可用于存储声明性信息的自定义属性,并且可以在运行时检索.根据设计标准和应用需求,此信息可与任何目标元素相关.

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

  • 声明自定义属性

  • 构建自定义属性

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

  • 通过反思访问属性

最后一步是编写一个简单的程序来读取元数据以查找各种表示法.元数据是关于用于描述其他数据的数据或信息的数据.该程序应使用反射来在运行时访问属性.我们将在下一章讨论.

声明自定义属性

新的自定义属性应该来自 System.Attribute 上课.例如,

//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 的自定义属性./p>

构造自定义属性


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

  • 错误的代码编号

  • 名称识别错误的开发人员

  • 上次审查代码的日期

  • 用于存储开发人员备注的字符串消息

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

每个属性必须至少有一个构造函数.位置参数应该通过构造函数传递.以下代码显示了 DeBugInfo 类 :

//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;
      }
   }
}


应用自定义属性

属性通过将其放置在其目标和减号之前立即应用;

[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类对象检索属性信息.