2010-03-02 35 views
19

在許多地方,我遇到FullTypeName, AssemblyName表格的部分限定類型名稱,即只有Type.AssemblyQualifiedName沒有版本,文化和publicKeyToken限定詞。如果給定部分限定類型名稱,Type.GetType如何工作?

我的問題是怎樣才能以最小的努力將其轉換爲各自的Type?我認爲Type.GetType做的工作,但唉,它不。下面的代碼,例如,返回null

Type.GetType("System.Net.Sockets.SocketException, System"); 

當然,如果我指定它的工作完全合格的名稱:

Type.GetType("System.Net.Sockets.SocketException, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"); 

非常感謝。

+0

你有在編譯時的類型?如果是這樣,爲什麼不使用typeof().FullName,et。人?如果您在運行時擁有類型,則可以使用 .GetType()。FullName et。人。或者我錯過了具體的要求?我知道你只想指定一個部分名稱,但對於裝載程序來說,這比對於類型系統更多。 FQN用於消除名稱衝突發生的罕見Occassions的引用問題,這在用戶程序集中比在BCL程序集中真實得多。 – GrayWizardx 2010-03-02 23:36:29

+1

我完全知道typeof()或Type.FullName。對象的類型是從配置文件中讀取的,這就是我使用Type.GetType的原因。這就是爲什麼我對理解部分合格類型名稱如何工作非常感興趣。 – mark 2010-03-03 07:17:48

回答

8

如果它所在的DLL尚未加載到應用程序域(例如,您使用它),則需要這樣的完整路徑,如果它已經加載,則可以使用較短的版本找到它。

要回答你的問題:第二個版本總是有效的,堅持下去,你有一種擔心的方式。

+1

我不認爲這個組件是否已經加載很重要 - 短版本不會工作。如果該類型在當前執行的程序集或mscorlib中,則名稱空間限定的名稱將起作用。下面更加詳細的解釋。 – lesscode 2015-01-06 14:03:54

2

代碼使用簡短形式的工作是:

Assembly a = Assembly.LoadWithPartialName(assemblyName); 
    Type t = a.GetType(typeName); 

但LoadWithPartialName已過時,所以我想你應該長期堅持的形式。

29

如果組件在當前域中被加載然後在下面通常的代碼工作:

public static Type GetTypeEx(string fullTypeName) 
{ 
    return Type.GetType(fullTypeName) ?? 
      AppDomain.CurrentDomain.GetAssemblies() 
        .Select(a => a.GetType(fullTypeName)) 
        .FirstOrDefault(t => t != null); 
} 

您可以使用它像這樣:

Type t = GetTypeEx("System.Net.Sockets.SocketException"); 
+1

非常感謝這個答案!這正是我所尋找的 - 比「接受」的答案好得多。 – 2012-07-24 21:06:33

+2

只要記住,這可能是非常緩慢的,所以不要忘記緩存.. – nawfal 2013-12-05 19:31:32

2

說完剛剛經歷了類似的問題,用了一些遺留代碼,我不認爲接受答案中的第一個陳述是正確的。這個組件是否已經加載並不重要。

根據文檔,Type.GetType(string)要求AssemblyQualifiedName,除非相關類型在當前正在執行的程序集或mscorlib中,在這種情況下,命名空間限定的類型名稱是全部所需的。

請注意,AssemblyQualifiedName包含類型的程序集的完整DisplayName(帶有版本,區域性和公鑰標記)。

短版本將無法工作,除非您用自定義AssemblyResolver(實際上是我的問題,掩蓋另一個問題)攔截失敗的類型加載。

0

True,Type.GetType(string)確實需要AssemblyQualifiedName。這可能是很多形式:

MyNS.MyType, MyAssembly, Version=x.x.x.x, Culture=xxx, PublicKeyToken=XXXXXXXXXX 

下也有效AssemblyQualifiedNames:

MyNS.MyType, MyAssembly, Version=x.x, Culture=xxx, PublicKeyToken=XXXXXXXXXX 
MyNS.MyType, MyAssembly, Culture=xxx, PublicKeyToken=XXXXXXXXXX 
MyNS.MyType, MyAssembly, PublicKeyToken=XXXXXXXXXX 
MyNS.MyType, MyAssembly 

對於簽名的程序集,對於FullyQualifiedAssemblyName所需的最小爲:

MyNS.MyType, MyAssembly, PublicKeyToken=XXXXXXXXXX 

對於無符號裝配,FullyQualifiedAssemblyName的最低要求是:

MyNS.MyType, MyAssembly 

不需要其他人提供的代碼片段中的「揮手」。確保您的類型名稱設置正確,並且可以高度靈活地訪問您的類型(並動態加載程序集)。我經常這樣做。

在OP的例如使用:

Type.GetType("System.Net.Sockets.SocketException, System") 

的失敗原因是缺乏的公鑰的。 .Net FW程序集都已簽名,因此需要PublicKeyToken才能解析程序集名稱。以下將工作:

Type.GetType("System.Net.Sockets.SocketException, System, PublicKeyToken=b77a5c561934e089") 
相關問題