Common Language Specification
更新:2007 年 11 月
若要充分與其他物件互動而不論實作它們的語言為何,這些物件必須只向呼叫端公開能在所有要交互作業之語言通用的功能。因而定義了 Common Language Specification (CLS),它是一組很多應用程式需要的基本語言功能。CLS 規則定義了一般型別系統的子集,也就是說,除了 CLS 中已經定義更嚴格規則的地方,所有適用於一般型別系統的規則都適用於 CLS。CLS 藉由定義一組開發人員可以在各種不同語言上使用的功能,來增進和確保語言的互通性。CLS 也建立了 CLS 符合性的需求;這些可以協助您判斷您的 Managed 程式碼是否符合 CLS,以及某種特定工具對於使用 CLS 功能之 Managed 程式碼的開發可以支援到什麼程度。
如果您的元件在它公開給其他程式碼 (包括衍生類別) 的 API 中只使用 CLS 功能,那麼保證從任何支援 CLS 的程式語言都能夠存取這個元件。遵循 CLS 規則和只使用 CLS 中所含功能的元件,就被稱為符合 CLS 標準的元件。
由 .NET Framework 類別庫概觀中型別所定義的大多數成員,都會符合 CLS 標準。但是,類別庫中也有些型別會擁有一或多個不符合 CLS 標準的成員。這些成員能夠支援 CLS 中所沒有的語言功能。這些不符合 CLS 標準的型別和成員都已標註於參考文件中,而且在所有情況下,都有符合 CLS 標準的替代項目可供使用。如需 .NET Framework 類別庫中型別的詳細資訊,請參閱 .NET Framework 類別庫參考。
CLS 在設計上就是希望能大到足夠包括開發人員通常所需的語言建構,而又要小到讓大部分語言都能夠支援它。除此而外,會導致無法快速驗證程式碼型別安全 (Type Safety) 的任何語言建構都已排除在 CLS 之外,讓所有符合 CLS 標準的語言都能產生可驗證的程式碼 (如果它們選擇這樣做的話)。如需型別安全驗證的詳細資訊,請參閱將 MSIL 編譯成機器碼。
以下表格摘要了 CLS 中的各項功能,並且指示這些功能是否同時適用於開發人員與編譯器兩者 (所有) 或僅適用於編譯器。它的目的在提供資訊,而非包羅萬象。如需詳細資訊,請參閱 Common Language Infrastructure Partition I 的規格,可從 Microsoft Developer Network 網站取得。
功能 |
適用於 |
說明 |
---|---|---|
一般 |
|
|
可視性 |
全部 |
CLS 規則只適用於在定義組件以外公開的型別部分。 |
全域成員 |
全部 |
全域靜態欄位和方法不符合 CLS 標準。 |
命名 |
|
|
字元和大小寫 |
全部 |
符合 CLS 標準的語言編譯器必須遵守 Unicode Standard 3.0 技術報告 15 附錄 7 的各項規則,它規定了可以啟始及包括在識別項中的字元集。這項標準可從 Unicode Consortium 的網站取得。 若要識兩個識別項被視為有區別,它們不能僅僅是大小寫不同而已。 |
關鍵字 |
編譯器 |
符合 CLS 標準的語言編譯器提供了一種機制,可參考與關鍵字相符之識別項。符合 CLS 標準的語言編譯器也提供了一種機制,可定義或強制取代其名稱為語言中關鍵字的虛擬方法。 |
唯一性 |
全部 |
在 符合 CLS 標準範圍內的所有名稱必須與其他名稱不同 (即使這些名稱是兩種不同的成員),但名稱相同且透過多載化 (Overloading) 解析者除外。例如,CLS 不允許單一型別對方法和欄位使用同樣的名稱。 |
簽章 |
全部 |
出現在型別或成員簽章 (Signature) 中的所有傳回型別和參數型別必須符合 CLS 標準。 |
型別 |
|
|
基本型別 |
全部 |
.NET Framework 類別庫包含了對應到編譯器所使用基本資料型別的型別。下列這些型別都符合 CLS 標準:Byte、Int16、Int32、Int64、Single、Double、Boolean、Char、Decimal、IntPtr 及 String。如需這些型別的詳細資訊,請參閱 .NET Framework 類別庫概觀中的型別表格。 |
Boxed 型別 |
全部 |
Boxed 實值型別 (尚未轉換為物件的實值型別) 不是 CLS 的一部分。請適當地使用 System.Object、System.ValueType 或 System.Enum。 |
可視性 |
全部 |
型別和成員宣告不可含有比被宣告之型別或成員更不容易看見或存取的型別。 |
介面方法 |
編譯器 |
符合 CLS 標準的語言編譯器必須擁有適合以下情況的語法:單一型別實作兩個介面,而且每個介面都需要具有相同名稱和簽章的方法定義。這些方法必須被視為不同,而且不需要相同的實作。 |
封閉性 |
全部 |
符合 CLS 標準的介面和抽象類別的個別成員必須被定義為符合 CLS 標準。 |
建構函式引動過程 |
全部 |
建構函式必須先呼叫基底類別的建構函式,然後才能存取任何繼承的執行個體資料。 |
具型別的參考 |
全部 |
具型別的參考不符合 CLS 標準(具型別的參考是一種含有物件參考和型別參考的特殊建構。具型別的參考可以讓 Common Language Runtime 對具有可變數目引數的方法提供 C++ 樣式支援)。 |
型別成員 |
|
|
多載化 |
全部 |
索引的屬性、方法和建構函式可以多載;欄位和事件則不可多載。 屬性不可由型別 (亦即,由其 Getter 方法的傳回型別) 多載,但是可以使用不同的索引數目或型別多載。 對於方法,只允許根據參數的數目和型別來多載,而且在泛型方法的情況下,只能根據這類方法的泛型參數數目。 運算子多載不在 CLS 規範中。但是,CLS 對於提供有用的名稱 (例如 Add()) 和設定中繼資料中的位元提供了一些指導原則。支援運算子多載的編譯器應該遵循這些指導原則,但是並非必須如此。 |
多載成員的唯一性 |
全部 |
欄位和巢狀型別必須僅以識別項比對來區別。具有相同名稱 (以識別項比對) 的方法、屬性和事件不可僅只是傳回型別不同而已。 |
轉換運算子 |
全部 |
如果 op_Implicit 或 op_Explicit 已多載於其傳回型別上,就必須提供另一種提供轉換的替代方式。 |
方法 |
|
|
被覆寫之方法的存取範圍 |
全部 |
在覆寫繼承的方法時,不得變更其存取範圍;但覆寫以 FamilyOrAssembly 存取範圍從不同組件所繼承的方法除外。在這種情況下,覆寫必須具有 Family 存取範圍。 |
引數清單 |
全部 |
CLS 所支援的唯一呼叫慣例是標準的 Managed 呼叫慣例;不允許可變長度引數清單 (如需可變數目的引數支援,請使用 Microsoft Visual Basic 中的 ParamArray 關鍵字,以及 C# 中的 params 關鍵字)。 |
屬性 |
|
|
存取子中繼資料 |
編譯器 |
實作屬性之方法的 Get 存取子和 Set 存取子方法,在中繼資料中會以 mdSpecialName 識別項所標記。 |
修飾詞 |
全部 |
屬性及其存取子必須全部為 static、全部為 virtual 或全部為 instance。 |
存取子名稱 |
全部 |
屬性必須遵循特定的命名模式。對於稱為 Name 的屬性,其 Get 存取子方法 (如果已定義) 將會被稱為 get_Name,而其 Set 存取子方法 (如果已定義) 將會被稱為 set_Name。 |
傳回型別和引數 |
全部 |
屬性的型別是 Get 存取子的傳回型別和 Set 存取子最後一個引數的型別。屬性參數的型別是 Get 存取子參數的型別和 Set 存取子除了最後一個參數之外的所有參數型別。所有這些型別都必須與 CLS 相容,而且不能是 Managed 指標;它們不能以傳址 (By Reference) 方式傳遞。 |
事件 |
|
|
事件方法 |
全部 |
加入和移除事件的方法,兩者必須同時存在或同時不存在。 |
事件方法中繼資料 |
編譯器 |
實作事件的方法在中繼資料中必須以 mdSpecialName 識別項標記。 |
存取子存取範圍 |
全部 |
加入、移除及引發事件之方法的存取範圍必須相同。 |
修飾詞 |
全部 |
加入、移除及引發事件的方法,必須全部為 static、全部為 virtual 或全部為 instance。 |
事件方法名稱 |
全部 |
事件必須遵循特定的命名模式。對於名為 MyEvent 的事件,其加入方法 (如果已定義) 將會命名為 add_MyEvent,其移除方法 (如果已定義) 將會命名為 remove_MyEvent,而其引發方法將會命名為 raise_MyEvent。 |
引數 |
全部 |
加入和移除事件的方法必須各自接受一個定義事件型別的參數,而且該型別必須是從 System.Delegate 衍生的。 |
指標型別 |
|
|
指標 |
全部 |
指標型別和函式指標型別都不符合 CLS 標準。 |
介面 |
|
|
成員簽章 |
全部 |
符合 CLS 標準的介面不可要求不符合 CLS 標準之方法的定義來實作它們。 |
成員修飾詞 |
全部 |
符合 CLS 標準的介面不可定義靜態方法,也不可定義欄位。它們可以定義屬性、事件及虛擬方法。 |
參考型別 |
|
|
建構函式引動過程 |
全部 |
對於參考型別,物件建構函式只會被呼叫做為建立物件的一部分,而且這些物件只會被初始化一次。 |
類別型別 |
|
|
繼承 |
全部 |
符合 CLS 標準的類別也必須繼承自符合 CLS 標準的類別 (System.Object 是符合 CLS 標準的)。 |
陣列1 |
|
|
元素型別 |
全部 |
陣列元素必須是符合 CLS 標準的型別。 |
維度 (Dimension) |
全部 |
陣列必須具有大於零的維度數目。 |
界限 |
全部 |
陣列的所有維度下限都必須為零。 |
列舉型別 |
|
|
基礎型別 |
全部 |
|
FlagsAttribute |
編譯器 |
在列舉型別的定義上出現的 System.FlagsAttribute 自訂屬性 (Attribute),表示應該將這個列舉型別視為一組位元欄位 (旗標);如果沒有出現這個屬性,則表示應該將這個型別視為列舉常數的群組。建議各種語言應使用 FlagsAttribute 或語言專用語法來區別這兩種列舉的型別。 |
欄位成員 |
全部 |
列舉型別的常值 (Literal) 靜態欄位必須與列舉型別本身同一型別。 |
例外狀況 |
|
|
繼承 |
全部 |
被擲回的物件必須是 System.Exception 型別,或是從 System.Exception 繼承的。 |
自訂屬性 |
|
|
值的編碼方式 |
編譯器 |
符合 CLS 標準的編譯器必須只處理自訂屬性編碼方式 (自訂屬性在中繼資料中的表示方式) 的子集。只有以下這些型別允許出現在這些編碼方式中:System.Type、System.String、System.Char、System.Boolean、System.Byte、System.Int16、System.Int32、System.Int64、System.Single、System.Double,以及以 CLS 標準基底整數型別為基礎的所有列舉型別。 |
中繼資料 |
|
|
CLS 符合性 |
全部 |
所擁有的 CLS 符合性與定義這些型別之組件的符合性不同的型別,都必須以 System.CLSCompliantAttribute 據實標記。同理,成員之 CLS 符合性與其型別不同者,亦應予以標記。如果將成員或型別標記為不符合 CLS 標準,就必須提供符合 CLS 標準的替代項目。 |
泛型 |
||
型別名稱 |
編譯器 |
泛型型別的名稱必須編碼型別上所宣告的型別參數的數目。巢狀泛型型別的名稱,則必須編碼新近引入型別的型別參數的數目。 |
巢狀型別 |
編譯器 |
巢狀型別必須至少有與封入型別 (Enclosing Type) 一樣多的泛型參數。巢狀型別中的泛型參數,都與在其封入型別中泛型參數的位置對應。 |
條件約束 |
全部 |
泛型型別必須宣告足夠的條件約束,才能保證泛型型別條件約束會滿足基底型別或介面上的所有條件約束。 |
條件約束型別 |
全部 |
用來做為泛型參數之條件約束的型別,本身也必須符合 CLS 標準。 |
成員簽章 |
全部 |
具現化 (Instantiated) 泛型型別中成員 (包括巢狀型別) 的可視性和存取範圍,一般都被視為屬於特定具現化的範圍,而非泛型型別宣告的範圍。 |
泛型方法 |
全部 |
對於每個抽象或虛擬泛型方法,都必須具有預設的具象 (非抽象) 實作。 |
1. 不規則陣列 (Jagged Array),也就是陣列的陣列,是符合 CLS 標準的。在 .NET Framework 1.0 版中,C# 編譯器錯誤報告這些項目不符合 CLS 標準。