下一节:

  C# 属性

  • 属性

    属性是一个用于传递信息至约各种元件等的类,方法,结构,统计,组件等在你的程序的行为的运行时的声明性代码。您可以使用属性将声明性信息添加到程序中。声明性标记由放置在所使用元素上方的方括号([])表示。属性用于将元数据(例如编译器指令)和其他信息(例如注释,描述,方法和类)添加到程序。.Net Framework提供了两种类型的属性:预定义属性自定义生成的属性
  • 指定属性

    指定属性的语法如下-
    
    [attribute(positional_parameters, name_parameter = value, ...)]
    element
    
    在将属性应用于元素之前,在方括号内指定属性名称及其值。位置参数指定基本信息,名称参数指定可选信息。
  • 预定义属性

    .Net Framework 提供了三个预定义的属性-
    • AttributeUsage
    • Conditional
    • Obsolete
  • 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)]
    
  • 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("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

    此预定义的属性标记了不应使用的程序实体。它使您可以通知编译器放弃特定的目标元素。例如,当在类中使用新方法时,如果您仍想在该类中保留旧方法,则可以通过显示一条消息,指出应该使用新方法而不是旧方法,将其标记为过时。
    指定此属性的语法如下-
    
    [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的自定义属性。
  • 构造自定义属性

    让我们构造一个名为DeBugInfo的自定义属性,该属性存储通过调试任何程序获得的信息。让它存储以下信息-
    • 错误的代码号
    • 识别错误的开发人员名称
    • 上次审核代码的日期
    • 用于存储开发人员评论的字符串消息
    DeBugInfo类有三个用于存储前三个信息的私有属性和一个用于存储消息的公共属性。因此,bug编号、开发人员姓名和检查日期是DeBugInfo类的位置参数,message 是可选的或指定的参数。每个属性必须至少有一个构造函数。位置参数应该通过构造函数传递。下面的代码显示了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());
       }
    }
    
    在下一章中,我们使用反射类对象检索属性信息。
下一节: