屬性 (C# 和 Visual Basic)
屬性 (Attribute) 提供一個有用的方法,使中繼資料 (或宣告式資訊) 與程式碼 (組件、型別、方法和屬性 (Property) 等) 產生關聯。 當屬性 (Attribute) 與程式實體 (Entity) 產生關聯之後,即可在執行階段使用稱為「反映」(Reflection) 的技術來加以查詢。 如需詳細資訊,請參閱反映 (C# 和 Visual Basic)。
屬性 (Attribute) 有下列屬性 (Property):
屬性會將中繼資料加入至程式。 「中繼資料」(Metadata) 是關於程式之已定義型別的資訊。 所有 .NET 組件都內含指定的中繼資料集,用來描述組件中已定義的型別和型別成員。 您可以加入自訂屬性,指定其他任何必要資訊。 如需詳細資訊,請參閱建立自訂屬性 (C# 和 Visual Basic)。
您可以將一或多個屬性 (Attribute) 套用至整個組件、模組或較小的程式項目,例如類別和屬性 (Property)。
屬性(Attribute) 接收引數的方式就和方法與屬性 (Property) 接受引數的方式一樣。
您的程式可以使用反映 (Reflection),檢查本身的中繼資料或其他程式內的中繼資料。 如需詳細資訊,請參閱使用反映存取屬性 (C# 和 Visual Basic)。
使用屬性
屬性 (Attribute) 可以放置在大部分的宣告中 (儘管特定的屬性可能限制其有效的宣告類型)。 在 C# 中,指定屬性的方式是將屬性的名稱括在方括弧 ([]) 中,並放置在要套用的實體之宣告上方。 在 Visual Basic 中,屬性是以角括弧 (< >) 括住, 而且必須緊靠在要套用的項目前面 (位於同一行)。
在這個範例中,會使用 SerializableAttribute 屬性將特定的特性套用至類別 (Class):
<System.Serializable()> Public Class SampleClass
' Objects of this type can be serialized.
End Class
[System.Serializable]
public class SampleClass
{
// Objects of this type can be serialized.
}
包含屬性 DllImportAttribute 的方法會以下列方式宣告:
Imports System.Runtime.InteropServices
...
<System.Runtime.InteropServices.DllImport("user32.dll")>
Sub SampleMethod()
End Sub
using System.Runtime.InteropServices;
...
[System.Runtime.InteropServices.DllImport("user32.dll")]
extern static void SampleMethod();
宣告中可放置一個以上的屬性:
Imports System.Runtime.InteropServices
...
Sub MethodA(<[In](), Out()> ByVal x As Double)
End Sub
Sub MethodB(<Out(), [In]()> ByVal x As Double)
End Sub
using System.Runtime.InteropServices;
...
void MethodA([In][Out] ref double x) { }
void MethodB([Out][In] ref double x) { }
void MethodC([In, Out] ref double x) { }
有些屬性可以指定給特定實體一次以上, ConditionalAttribute 就是這種多次使用屬性的一個例子:
<Conditional("DEBUG"), Conditional("TEST1")>
Sub TraceMethod()
End Sub
[Conditional("DEBUG"), Conditional("TEST1")]
void TraceMethod()
{
// ...
}
注意事項 |
---|
依照慣例,所有屬性名稱都是以 "Attribute" 這個字做為結尾,以便辨別屬性與 .NET Framework 中的其他項目。但是在程式碼中使用屬性時,並不需要指定屬性字尾。例如,[DllImport] 相同於 [DllImportAttribute],但在 .NET Framework 中,屬性的實際名稱是 DllImportAttribute。 |
屬性參數
許多屬性都具有參數,可以是位置、不具名或具名參數。 任何位置 (Positional) 參數必須以特定的順序指定並且不能省略;具名參數是選擇性的並且可以任何順序指定, 而位置參數會先指定。 例如,這三個屬性相等:
[DllImport("user32.dll")]
[DllImport("user32.dll", SetLastError=false, ExactSpelling=false)]
[DllImport("user32.dll", ExactSpelling=false, SetLastError=false)]
<DllImport("user32.dll")>
<DllImport("user32.dll", SetLastError:=False, ExactSpelling:=False)>
<DllImport("user32.dll", ExactSpelling:=False, SetLastError:=False)>
第一個參數為 DLL 名稱,是位置參數而且一定排在首位;其他都是具名參數。 在此情況下,由於兩個具名參數預設都是 false,因此都會遭到省略。 如需預設參數值的資訊,請參閱個別屬性的文件。
屬性目標
屬性的「目標」(Target) 就是屬性要套用的實體。 例如,屬性可以套用到類別、特定方法或整個組件。 根據預設,屬性會套用到接在其後面的項目。 但是您也可以明確識別屬性要套用的對象,例如屬性是要套用到方法、套用到其參數,還是要套用到其傳回值。
若要明確識別屬性目標,請使用下列語法:
[target : attribute-list]
<target : attribute-list>
下表列出可能的 target 值。
C# |
Visual Basic |
適用於 |
---|---|---|
assembly |
Assembly |
整個組件 |
module |
Module |
目前的組件模組 (其與 Visual Basic 模組不同) |
field |
不支援 |
類別或結構中的欄位 |
event |
不支援 |
事件 |
method |
不支援 |
方法或 get 和 set 屬性存取子 |
param |
不支援 |
方法參數或 set 屬性存取子參數 |
property |
不支援 |
屬性 |
return |
不支援 |
方法的傳回值、屬性索引子或 get 屬性存取子。 |
type |
不支援 |
結構、類別、介面、列舉或委派 |
下列範例示範如何將屬性套用到組件和模組。 如需詳細資訊,請參閱常見屬性 (C# 和 Visual Basic)。
Imports System.Reflection
<Assembly: AssemblyTitleAttribute("Production assembly 4"),
Module: CLSCompliant(True)>
using System;
using System.Reflection;
[assembly: AssemblyTitleAttribute("Production assembly 4")]
[module: CLSCompliant(true)]
下列範例示範如何在 C# 中將屬性套用到方法、方法參數和方法傳回值。
// default: applies to method
[SomeAttr]
int Method1() { return 0; }
// applies to method
[method: SomeAttr]
int Method2() { return 0; }
// applies to return value
[return: SomeAttr]
int Method3() { return 0; }
注意事項 |
---|
不論 SomeAttr 定義為有效之目標為何,都必須指定 return 目標,即使 SomeAttr 已定義為只套用到傳回值也一樣。換句話說,編譯器將不會使用 AttributeUsage 資訊來解析模稜兩可的屬性目標。如需詳細資訊,請參閱AttributeUsage (C# 和 Visual Basic)。 |
屬性的常見用法
下列清單包括屬性在程式碼中的一些通用用法:
使用 Web 服務中的 WebMethod 屬性來標記方法,指出應可透過 SOAP 通訊協定來呼叫方法。 如需詳細資訊,請參閱WebMethodAttribute。
描述與機器碼相互操作時如何封送處理方法參數。 如需詳細資訊,請參閱MarshalAsAttribute。
描述類別、方法和介面的 COM 屬性。
使用 DllImportAttribute 類別呼叫 Unmanaged 程式碼。
從標題、版本、描述或商標的角度來描述組件。
描述為了保存性 (Persistence) 要序列化類別的哪些成員。
描述如何在類別成員和 XML 節點之間對應以進行 XML 序列化 (Serialization)。
描述方法的安全性要求。
指定用來強制使用安全性的特性。
藉由 Just-in-Time (JIT) 編譯器來控制最佳化,如此就能輕易地為程式碼進行偵錯。
取得呼叫端的資訊的方法。
相關章節
如需詳細資訊,請參閱: