System.Type.GetType 方法
本文提供此 API 參考文件的補充備註。
GetType(String, Func<AssemblyName,Assembly>, Func<Assembly,String,Boolean,Type>, Boolean, Boolean)使用 方法多載及其相關聯的多載 (GetType(String, Func<AssemblyName,Assembly>, Func<Assembly,String,Boolean,Type>)和 GetType(String, Func<AssemblyName,Assembly>, Func<Assembly,String,Boolean,Type>, Boolean)),以更有彈性的GetType實作取代方法的默認實作。 藉由提供您自己的方法來解析類型名稱和包含它們的元件名稱,您可以執行下列動作:
- 控制從中載入類型的元件版本。
- 提供另一個位置來尋找不包含元件名稱的類型名稱。
- 使用部分元件名稱載入元件。
- 傳回 Common Language Runtime (CLR) 未建立的子類別 System.Type 。
例如,在版本容錯串行化中,這個方法可讓您使用部分名稱來搜尋「最適合」的元件。 方法的其他多載 GetType 需要元件限定的類型名稱,其中包含版本號碼。
型別系統的替代實作可能需要傳回 CLR 未建立的GetType子類別System.Type;方法其他多載所傳回的所有類型都是運行時間類型。
使用量注意事項
這個方法多載及其相關聯的多載會剖析 typeName
為型別的名稱和元件的名稱,然後解析名稱。 元件名稱的解析會在類型名稱解析之前發生,因為必須在元件的內容中解析類型名稱。
注意
如果您不熟悉元件限定類型名稱的概念,請參閱 AssemblyQualifiedName 屬性。
如果 typeName
不是元件限定名稱,則會略過元件解析。 在mscorlib.dll/System.Private.CoreLib.dll或目前正在執行的元件的內容中,或您可以選擇性地在 參數中 typeResolver
提供元件,以解析不合格的類型名稱。 包含或省略不同類型名稱解析元件名稱的效果會顯示為混合名稱解析區段中的數據表。
一般使用注意事項:
請勿將方法
assemblyResolver
傳遞給 或typeResolver
,如果它們來自未知或未受信任的呼叫端。 只使用您所提供或熟悉的方法。警告
使用來自未知或未受信任呼叫端的方法可能會導致惡意代碼的許可權提升。
如果您省略
assemblyResolver
和/或typeResolver
參數,參數的值throwOnError
會傳遞至執行預設解析的方法。如果
throwOnError
為true
,則這個方法會在 TypeLoadException 傳回 時typeResolver
擲回null
,而 FileNotFoundException 當 傳回 時assemblyResolver
會擲回null
。這個方法不會攔截 和
typeResolver
擲回的assemblyResolver
例外狀況。 您負責解析程式方法擲回的任何例外狀況。
解析元件
方法 assemblyResolver
會 AssemblyName 接收 物件,其產生方式是剖析 中包含的 typeName
字串元件名稱。 如果 typeName
不包含元件名稱, assemblyResolver
則不會呼叫 ,而且 null
會傳遞至 typeResolver
。
如果未 assemblyResolver
提供,則會使用標準元件探查來找出元件。 如果 assemblyResolver
提供 ,則 GetType 方法不會執行標準探查;在此情況下,您必須確定 assemblyResolver
可以處理您傳遞給它的所有元件。
如果無法解析元件,方法 assemblyResolver
應該會傳回 null
。 如果 assemblyResolver
傳 null
回 , typeResolver
則不會呼叫 ,而且不會進一步處理;此外,如果 throwOnError
為 true
, FileNotFoundException 則會擲回 。
AssemblyName如果傳遞至 assemblyResolver
的 是部分名稱,則其一或多個部分為 null
。 例如,如果沒有版本,則 Version 屬性為 null
。 Version如果屬性、CultureInfo屬性和 GetPublicKeyToken 方法全都傳回 null
,則只會提供元件的簡單名稱。 assemblyResolver
方法可以使用或忽略元件名稱的所有部分。
不同元件解析選項的效果會顯示為混合名稱解析區段中的數據表,以取得簡單和元件限定的類型名稱。
解析類型
如果未 typeName
指定元件名稱, typeResolver
則一律會呼叫 。 如果 typeName
指定元件名稱, typeResolver
只有在成功解析元件名稱時,才會呼叫 。 如果 assemblyResolver
或標準元件探查傳 null
回 , typeResolver
則不會呼叫 。
方法 typeResolver
會接收三個自變數:
- 要搜尋的
null
元件,如果typeName
不包含元件名稱,則為 。 - 型別的簡單名稱。 在巢狀類型的情況下,這是最外層的包含類型。 在泛型型別的情況下,這是泛型型別的簡單名稱。
- 布爾值,表示
true
要忽略類型名稱的案例。
實作會決定使用這些自變數的方式。 typeResolver
如果方法無法解析類型,則應該會傳回 null
。 如果 typeResolver
傳 null
回 且 throwOnError
為 true
,這個 的 GetType 多載會 TypeLoadException擲回 。
不同類型解析選項的效果會顯示為混合名稱解析區段中的數據表,以取得簡單和元件限定的類型名稱。
解析巢狀類型
如果 typeName
是巢狀類型,則只會將包含型別的最外層名稱傳遞至 typeResolver
。 傳回此類型時 typeResolver
, GetNestedType 方法會以遞歸方式呼叫,直到解析最內部的巢狀類型為止。
解析泛型類型
GetType會以遞歸方式呼叫 來解析泛型型別:首先解析泛型型別本身,然後解析其型別自變數。 如果類型自變數是泛型, GetType 則會以遞歸方式呼叫 ,以解析其類型自變數等等。
assemblyResolver
和 typeResolver
的組合必須能夠解析此遞歸的所有層級。 例如,假設您提供 assemblyResolver
控制載入的 MyAssembly
。 假設您想要解析泛型類型 Dictionary<string, MyType>
(Dictionary(Of String, MyType)
在 Visual Basic 中)。 您可以傳遞下列泛型型型型:
"System.Collections.Generic.Dictionary`2[System.String,[MyNamespace.MyType, MyAssembly]]"
請注意, MyType
這是唯一的元件限定型別自變數。 和 String 類別的名稱Dictionary<TKey,TValue>不是元件限定的。 您必須 typeResolver
能夠處理元件或 null
,因為它將接收 null
Dictionary<TKey,TValue> 和 String。 它可以藉由呼叫接受字串之方法的多 GetType 載來處理該案例,因為兩個不合格的型別名稱都在mscorlib.dll/System.Private.CoreLib.dll中:
Type t = Type.GetType(test,
(aName) => aName.Name == "MyAssembly" ?
Assembly.LoadFrom(@".\MyPath\v5.0\MyAssembly.dll") : null,
(assem, name, ignore) => assem == null ?
Type.GetType(name, false, ignore) :
assem.GetType(name, false, ignore)
);
let t =
Type.GetType(test,
(fun aName ->
if aName.Name = "MyAssembly" then
Assembly.LoadFrom @".\MyPath\v5.0\MyAssembly.dll"
else null),
fun assem name ignr ->
if assem = null then
Type.GetType(name, false, ignr)
else
assem.GetType(name, false, ignr))
不會 assemblyResolver
針對字典類型和字串類型呼叫 方法,因為這些類型名稱不是元件限定名稱。
現在假設 不是 System.String
,第一個泛型自變數類型是從 YourType
YourAssembly
:
"System.Collections.Generic.Dictionary`2[[YourNamespace.YourType, YourAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null], [MyNamespace.MyType, MyAssembly]]"
因為這個元件既不是mscorlib.dll/System.Private.CoreLib.dll也不是目前正在執行的元件,所以您無法在沒有元件限定名稱的情況下解析 YourType
。 因為會以遞歸方式呼叫您的 assemblyResolve
,所以必須能夠處理此案例。 它現在會使用提供的 AssemblyName 物件執行元件載入,而不是針對 以外的MyAssembly
元件傳回 null
。
Type t2 = Type.GetType(test,
(aName) => aName.Name == "MyAssembly" ?
Assembly.LoadFrom(@".\MyPath\v5.0\MyAssembly.dll") :
Assembly.Load(aName),
(assem, name, ignore) => assem == null ?
Type.GetType(name, false, ignore) :
assem.GetType(name, false, ignore), true
);
let t2 =
Type.GetType(test,
(fun aName ->
if aName.Name = "MyAssembly" then
Assembly.LoadFrom @".\MyPath\v5.0\MyAssembly.dll"
else Assembly.Load aName),
(fun assem name ignr ->
if assem = null then
Type.GetType(name, false, ignr)
else
assem.GetType(name, false, ignr)), true)
使用特殊字元解析類型名稱
某些字元在元件限定名稱中具有特殊意義。 如果簡單類型名稱包含這些字元,當簡單名稱是元件限定名稱的一部分時,字元會造成剖析錯誤。 若要避免剖析錯誤,您必須先使用反斜杠逸出特殊字元,才能將元件限定名稱傳遞至 GetType 方法。 例如,如果類型命名 Strange]Type
為 ,則必須在方括弧前面加入逸出字元,如下所示: Strange\]Type
。
注意
具有這類特殊字元的名稱無法在 Visual Basic 或 C# 中建立,但可以使用通用中繼語言 (CIL) 或發出動態元件來建立。
下表顯示類型名稱的特殊字元。
字元 | 意義 |
---|---|
, (逗號) |
元件限定名稱的分隔符。 |
[] (方括弧) |
做為後綴組,表示陣列類型;以分隔符組的形式括住泛型自變數清單和元件限定名稱。 |
& (& 符號) |
做為後綴,表示類型是參考型別。 |
* (星號) |
做為後綴,表示類型是指針類型。 |
+ (加) |
巢狀類型的分隔符。 |
\ (反斜杠) |
逸出字元。 |
屬性,例如 AssemblyQualifiedName 傳回正確逸出字串。 您必須將正確逸出字串傳遞至 GetType 方法。 接著,方法會將 GetType 正確逸出的名稱 typeResolver
傳遞給 默認類型解析方法, 如果您需要在 中 typeResolver
比較名稱與未逸出的名稱,則必須移除逸出字元。
混合名稱解析
下表摘要說明 中所有類型名稱和元件名稱typeName
組合的、 typeResolver
和 預設名稱解析之間的assemblyResolver
互動:
類型名稱的內容 | 元件解析程式方法 | 類型解析程式方法 | 結果 |
---|---|---|---|
type、 assembly | null | null | 相當於呼叫 Type.GetType(String, Boolean, Boolean) 方法多載。 |
type、 assembly | 提供 | null | assemblyResolver 會傳回元件,如果無法解析元件,則傳回 null 。 如果已解析元件,則會 Assembly.GetType(String, Boolean, Boolean) 使用 方法多載從元件載入類型,否則不會嘗試解析類型。 |
type、 assembly | null | 提供 | 相當於將元件名稱 AssemblyName 轉換成 物件,並呼叫 Assembly.Load(AssemblyName) 方法多載以取得元件。 如果已解析元件,則會傳遞至 typeResolver ,否則 typeResolver 不會呼叫 ,而且不會再嘗試解析類型。 |
type、 assembly | 提供 | 提供 | assemblyResolver 會傳回元件,如果無法解析元件,則傳回 null 。 如果已解析元件,則會傳遞至 typeResolver ,否則 typeResolver 不會呼叫 ,而且不會再嘗試解析類型。 |
type | null,提供 | null | 相當於呼叫 Type.GetType(String, Boolean, Boolean) 方法多載。 因為未提供元件名稱,因此只會搜尋mscorlib.dll/System.Private.CoreLib.dll和目前正在執行的元件。 如果 assemblyResolver 提供 ,則會忽略它。 |
type | null,提供 | 提供 | typeResolver 會呼叫 ,並 null 傳遞給元件。 typeResolver 可以從任何元件提供類型,包括它為了目的載入的元件。 如果 assemblyResolver 提供 ,則會忽略它。 |
assembly | null,提供 | null,提供 | FileLoadException擲回 ,因為元件名稱會剖析為元件限定型別名稱。 這會導致元件名稱無效。 |