屬性是一個聲明性的標簽,用于向運行時傳遞有關(guān)程序中各種元素(如類,方法,結(jié)構(gòu),枚舉器,程序集等)的行為的信息??梢酝ㄟ^使用屬性將聲明性信息添加到程序。聲明式標簽由放置在其所用元素上方的方括號([]
)表示。
屬性用于向程序添加元數(shù)據(jù),如編譯器指令和其他信息,如注釋,描述,方法和類。.Net框架提供了兩種類型的屬性:預(yù)定義屬性和自定義構(gòu)建的屬性。
用于指定屬性的語法如下:
[attribute(positional_parameters, name_parameter = value, ...)]
element
屬性名稱及其值在方括號內(nèi),在應(yīng)用該屬性的元素之前指定。位置參數(shù)指定必要信息,名稱參數(shù)指定可選信息。
.Net
框架提供了三個預(yù)定義的屬性:
預(yù)定義屬性AttributeUsage
描述了如何使用自定義屬性類。它指定可以應(yīng)用該屬性的項目的類型。
用于指定此屬性的語法如下:
[AttributeUsage(
validon,
AllowMultiple=allowmultiple,
Inherited=inherited
)]
其中,
validon
指定可以放置屬性的語言元素。它是枚舉器AttributeTargets
的值的組合。默認值為AttributeTargets.All
。allowmultiple
(可選)為此屬性的AllowMultiple
屬性提供了一個布爾值。 如果些值為:true
,則表示屬性是多次使用。默認值為false
,表示一次性使用。inherited
(可選)為此屬性的Inherited
屬性提供了一個布爾值。 如果此參數(shù)值為:true
,則屬性由派生類繼承。 它默認值為false
(不繼承)。例如,
[AttributeUsage(AttributeTargets.Class |
AttributeTargets.Constructor |
AttributeTargets.Field |
AttributeTargets.Method |
AttributeTargets.Property,
AllowMultiple = true)]
此預(yù)定義屬性標記一個條件方法,其執(zhí)行取決于指定的預(yù)處理標識符。
它使方法調(diào)用條件編譯,具體取決于指定的值,如:調(diào)試(Debug
)或跟蹤(Trace
)。 例如,它在調(diào)試代碼時顯示變量的值。
用于指定此屬性的語法如下:
[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();
}
}
當上述代碼被編譯并執(zhí)行時,它產(chǎn)生以下結(jié)果:
In Main function
In Function 1
In Function 2
此預(yù)定義屬性標記不應(yīng)該使用的程序?qū)嶓w。它能夠通知編譯器丟棄特定的目標元素。 例如,當一個類中正在使用一個新方法,并且如果仍然希望在類中保留舊方法時,可以通過顯示新方法而不是舊方法來顯示消息來將其標記為過時。
用于指定此屬性的語法如下:
[Obsolete(
message
)]
[Obsolete(
message,
iserror
)]
其中,
message
是一個字符串,描述項目過時的原因以及使用的替代方法。iserror
,是一個布爾值。 如果值為true
,則編譯器應(yīng)將該項目的使用視為錯誤。默認值為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框架允許創(chuàng)建可用于存儲聲明性信息的自定義屬性,并可在運行時檢索。該信息可以根據(jù)設(shè)計標準和應(yīng)用需要與任何目標元素相關(guān)。
創(chuàng)建和使用自定義屬性涉及四個步驟:
最后一步是編寫一個簡單的程序來讀取元數(shù)據(jù)以找到各種標記。元數(shù)據(jù)是用于描述其他數(shù)據(jù)的數(shù)據(jù)或信息。程序可在運行時訪問屬性的反射。這將在下一章討論。
應(yīng)該從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
的自定義屬性。
下面來構(gòu)建一個名稱為DeBugInfo
的自定義屬性,它存儲通過調(diào)試任何程序獲得的信息。它存儲以下信息:
DeBugInfo
類有三個私有屬性用于存儲前三個信息和一個用于存儲消息的公共屬性。 因此,錯誤編號,開發(fā)人員名稱和審查日期是DeBugInfo
類的位置參數(shù),并且消息是可選的或命名的參數(shù)。
每個屬性必須至少有一個構(gòu)造函數(shù)。位置參數(shù)應(yīng)通過構(gòu)造函數(shù)傳遞。以下代碼顯示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;
}
}
}
該屬性是通過放置在目標之前來應(yīng)用:
[DeBugInfo(45, "Maxsu", "12/8/2018", Message = "Return type mismatch")]
[DeBugInfo(49, "Sukyda", "10/10/2018", 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, "Maxsu", "19/10/2018", Message = "Return type mismatch")]
public double GetArea()
{
return length * width;
}
[DeBugInfo(56, "Maxsu", "19/10/2018")]
public void Display()
{
Console.WriteLine("Length: {0}", length);
Console.WriteLine("Width: {0}", width);
Console.WriteLine("Area: {0}", GetArea());
}
}
在下一章中,使用Reflection
類對象檢索屬性信息。