XML 檔案檔案處理
編譯器會針對程式碼中,標記為要產生文件的每個建構產生識別碼字串。 如需詳細資訊,請參閱 建議的標籤檔批註。 識別碼字串可唯一識別此建構。 處理 XML 檔案的程式可以使用識別符字串來識別檔適用的對應 .NET Framework 元數據或反映專案。
XML 檔案不是程式碼的階層表示法,它是具有每個元素所產生標識碼的一般清單。
編譯器在產生識別碼字串時會遵守下列規則:
字串中未放置任何空白字元。
識別碼字串的第一個部分會識別所識別的成員種類,格式為單一字元後面接著一個冒號。 使用的成員類型如下:
字元 描述 否 Namespace
您無法將檔批註新增至命名空間,可以建立命名空間的參考。T 類型:類別、介面、結構、列舉、委派 D Typedef F 欄位 P 屬性(包括索引器或其他索引屬性) 月 方法(包括建構函式、運算子等特殊方法) E 活動 ! 錯誤字串
字串的其餘部分提供與錯誤相關的資訊。 MSVC 編譯程式會產生無法解析的連結錯誤資訊。字串的第二個部分是項目的完整名稱 (從命名空間的根開始)。 項目名稱、其封入類型及命名空間會以句號來分隔。 如果項目名稱本身包含句點,則會以雜湊符號 ('#') 來加以取代。 假設沒有項目的名稱中直接含有雜湊符號。 例如,
String
建構函式的完整名稱會是System.String.#ctor
。針對屬性和方法,如果有方法的引數,則後面會接著以括弧括住的引數清單。 如果沒有任何引數,就不會出現括弧。 引數會以逗號分隔。 每個自變數的編碼方式都與在 .NET Framework 簽章中編碼的方式相同:
基底類型。 一般型別 (
ELEMENT_TYPE_CLASS
或ELEMENT_TYPE_VALUETYPE
) 會以型別的完整名稱表示。內建型別 (例如 ,
ELEMENT_TYPE_I4
、ELEMENT_TYPE_STRING
ELEMENT_TYPE_OBJECT
ELEMENT_TYPE_TYPEDBYREF
、 和ELEMENT_TYPE_VOID
) 會表示為對應完整型別的完整名稱,例如System.Int32
或 。System.TypedReference
ELEMENT_TYPE_PTR
在修改的類型之後,會以 『*
' 表示。ELEMENT_TYPE_BYREF
在修改的類型之後,會以 『@
' 表示。ELEMENT_TYPE_PINNED
在修改的類型之後,會以 『^
' 表示。 MSVC 編譯程序永遠不會產生這個專案。ELEMENT_TYPE_CMOD_REQ
在修改的類型之後,會以 『|
' 和修飾詞類別的完整名稱表示。 MSVC 編譯程序永遠不會產生這個專案。ELEMENT_TYPE_CMOD_OPT
在修改的類型之後,會以 『!
' 和修飾詞類別的完整名稱表示。ELEMENT_TYPE_SZARRAY
在陣列的元素類型之後,會以 “[]
”“表示。ELEMENT_TYPE_GENERICARRAY
在陣列的元素類型之後,會以 “[?]
”“表示。 MSVC 編譯程序永遠不會產生這個專案。ELEMENT_TYPE_ARRAY
表示為[
下限大小的下限:
:
大小,
]
,其中逗號數目是排名 - 1,而每個維度的下限和大小,如果已知,則會以十進位表示。 如果未指定下限或大小,就會加以省略。 如果特定維度省略下限和大小,則會省略 ':
' 。 例如,以 1 做為下限且未指定大小的 2 維陣列會以 表示。[1:,1:]
ELEMENT_TYPE_FNPTR
會表示為 "=FUNC:type
(signature)",其中type
是傳回型別,而 signature 是方法的引數。 如果沒有任何引數,就會省略括弧。 MSVC 編譯程序永遠不會產生這個專案。
不會表示下列簽章元件,因為它們永遠不會用於區分多載方法:
呼叫慣例
傳回類型
ELEMENT_TYPE_SENTINEL
只有轉換運算符,方法的傳回值會編碼為 『
~
',後面接著傳回型別,如先前編碼。針對泛型類型,類型的名稱後面將接著反引號,然後是表示泛型類型參數數目的數字。 例如,
<member name="T:MyClass`2">
此範例顯示定義為
public class MyClass<T, U>
的型別。對於採用泛型型別做為參數的方法,泛型型別參數會指定為前面加上後刻度的數位(例如 '0,'1)。 每個數位都代表類型泛型參數以零起始的陣列位置。
範例
下列範例顯示針對類別及其成員產生識別碼字串的方式。
// xml_id_strings.cpp
// compile with: /clr /doc /LD
///
namespace N {
// "N:N"
/// <see cref="System" />
// <see cref="N:System"/>
ref class X {
// "T:N.X"
protected:
///
!X(){}
// "M:N.X.Finalize", destructor's representation in metadata
public:
///
X() {}
// "M:N.X.#ctor"
///
static X() {}
// "M:N.X.#cctor"
///
X(int i) {}
// "M:N.X.#ctor(System.Int32)"
///
~X() {}
// "M:N.X.Dispose", Dispose function representation in metadata
///
System::String^ q;
// "F:N.X.q"
///
double PI;
// "F:N.X.PI"
///
int f() { return 1; }
// "M:N.X.f"
///
int bb(System::String ^ s, int % y, void * z) { return 1; }
// "M:N.X.bb(System.String,System.Int32@,System.Void*)"
///
int gg(array<short> ^ array1, array< int, 2 >^ IntArray) { return 0; }
// "M:N.X.gg(System.Int16[], System.Int32[0:,0:])"
///
static X^ operator+(X^ x, X^ xx) { return x; }
// "M:N.X.op_Addition(N.X,N.X)"
///
property int prop;
// "M:N.X.prop"
///
property int prop2 {
// "P:N.X.prop2"
///
int get() { return 0; }
// M:N.X.get_prop2
///
void set(int i) {}
// M:N.X.set_prop2(System.Int32)
}
///
delegate void D(int i);
// "T:N.X.D"
///
event D ^ d;
// "E:N.X.d"
///
ref class Nested {};
// "T:N.X.Nested"
///
static explicit operator System::Int32 (X x) { return 1; }
// "M:N.X.op_Explicit(N.X!System.Runtime.CompilerServices.IsByValue)~System.Int32"
};
}