2009-12-01 55 views
159

此代碼:Type.GetType( 「namespace.a.b.ClassName」)返回null

Type.GetType("namespace.a.b.ClassName") 

回報null

,我有在usings:

using namespace.a.b; 

更新:

類型存在,它在不同的類庫,我需要通過字符串名稱來得到它。

+0

看到這個https://開頭計算器。com/questions/441680/how-can-i-retrieve-an-assemblys-qualified-type-name有關如何獲取程序集限定名的信息。 – Polyfun 2009-12-01 11:19:42

回答

179

Type.GetType("namespace.qualified.TypeName")僅當在mscorlib.dll或當前正在執行的程序集中找到該類型時纔有效。

如果這些都不是真的,你需要一個assembly-qualified name

+1

該類型存在,它在不同的類庫中,我需要通過字符串名稱得到它 – Omu 2009-12-01 09:58:50

+108

可惜您沒有提供任何示例。 – Shimmy 2010-10-05 03:15:25

+1

@Shimmy http://stackoverflow.com/a/3512351/1540350 – modiX 2014-07-20 22:15:47

4

如果組件引用和類可見:因爲類型沒有找到

typeof(namespace.a.b.ClassName) 

的GetType返回null,用typeof,編譯器可以幫助你找出錯誤。

+0

類型存在,它在不同的類庫,我需要通過字符串名稱 – Omu 2009-12-01 10:00:34

7

如果它是一個嵌套類型,你可能會忘記轉換一個。到+

無論如何,typeof(T).FullName會告訴你什麼,你應該說

編輯:BTW的usings(我敢肯定你知道)僅指令編譯器在編譯時並不能因此有任何影響API調用的成功。 (如果你有項目或組裝的參考,也可能有過影響 - 因此信息心不是沒用,只是需要一些過濾...)

+0

哦,我的!你知道這個「+」 - 語法是在哪裏解釋的嗎? – 2017-03-08 10:14:54

+1

Protectorone我從https://www.amazon.com/Essential-NET-Common-Language-Runtime/dp/0201734117 IIRC瞭解到,但這有點過時。我可以推薦https://www.amazon.com/CLR-via-4th-Developer-Reference/dp/0735667454/ref=sr_1_1?s=books&ie=UTF8&qid=1489044599&sr=1-1&keywords=clr+via+c%23作爲所有.NET開發人員非常有用的書籍?包括這個?底線是類型,CLR只有名稱空間和名稱 - 嵌套類型不能直接尋址。因此,如果一種語言具有嵌套類型概念,就可以做到它所需要的東西(儘管一般來說大多數語言都使用「+」分隔符) – 2017-03-09 07:32:58

24
Dictionary<string, Type> typeCache; 
... 
public static bool TryFindType(string typeName, out Type t) { 
    lock (typeCache) { 
     if (!typeCache.TryGetValue(typeName, out t)) { 
      foreach (Assembly a in AppDomain.CurrentDomain.GetAssemblies()) { 
       t = a.GetType(typeName); 
       if (t != null) 
        break; 
      } 
      typeCache[typeName] = t; // perhaps null 
     } 
    } 
    return t != null; 
} 
+1

這看起來不錯,但是使用其他裝配類型的泛型又如何呢? – 2016-05-24 10:10:24

3

嘗試使用包括裝配信息完整的類型名稱,例如:

string typeName = @"MyCompany.MyApp.MyDomain.MyClass, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"; 
Type myClassType = Type.GetType(typeName); 

我時,我只用了namesspace.classname獲取類的在不同的裝配類型相同的情況下,它是行不通的。只有當我在我的類型字符串中包含程序集信息時才起作用,如上所示。

148

您還可以獲得類型無裝配合格的名稱,但使用DLL名稱還舉例說:

Type myClassType = Type.GetType("TypeName,DllName"); 

我有同樣的情況,它爲我工作。我需要類型的對象「DataModel.QueueObject」,不得不提及「的DataModel」所以我得到的類型如下:

Type type = Type.GetType("DataModel.QueueObject,DataModel"); 

逗號後的第二字符串是參考名稱(DLL名稱)。

+2

這是一個'技巧'還是一個實際的方法?我無法在文檔-_-中找到它。順便說一句,它結束了我1周的痛苦!謝謝 – DnR 2014-12-29 02:41:55

+1

這是一個更清潔的解決方案,我很想看看是否有任何陷阱因此。 – cossacksman 2015-11-20 14:43:24

+3

此答案中使用的表單也是完全限定類型名稱[根據MSDN語法](https://msdn.microsoft.com/en-us/library/yfsftwz6(v = vs.110).aspx)(所以它不是_trick_)。表單是'NamespaceTypeName,AssemblyNameSpec',其中'AssemblyNameSpec'是沒有任何屬性的程序集標識符。儘管這個答案基本上與被接受的一樣,但我認爲有些人更喜歡這個,因爲它消除了程序集屬性引入的一些「噪音」(例如'Version','Culture'' PublicKeyToken')。幸運的是,這些屬性是__optional__。 – 2016-05-18 14:26:02

59

嘗試使用這種方法

public static Type GetType(string typeName) 
     { 
      var type = Type.GetType(typeName); 
      if (type != null) return type; 
      foreach (var a in AppDomain.CurrentDomain.GetAssemblies()) 
      { 
       type = a.GetType(typeName); 
       if (type != null) 
        return type; 
      } 
      return null ; 
     } 
+0

這實際上是爲我工作的。但是,我不得不通過在foreach循環之前添加一個子字符串trim來調整,因爲我傳入了一個程序集限定的名稱,而Assembly.GetType()僅在排除程序集信息時才起作用。 – Colin 2015-02-17 19:00:24

+0

這看起來不錯,但是使用其他裝配類型的泛型又如何呢? – 2016-05-24 10:10:35

+0

對於UWP不起作用,因爲不支持「AppDomain」。不確定任何替代品。 – 2017-03-21 21:17:53

22

如果組件是ASP的構建的一部分。NET應用程序,您可以使用BuildManager類:

using System.Web.Compilation 
... 
BuildManager.GetType(typeName, false); 
+1

這是一個很好的答案,應該在頁面上更高。與獲取程序集的合格類型名稱的舊方法相比,它像魅力一樣工作並且簡單。 – Graham 2014-02-04 19:18:27

+0

這是驚人的簡單和現貨,你能幫我反射對象的性能優化? – Alok 2018-02-25 17:52:28

5

我打開用戶控件,取決於用戶有權訪問數據庫中指定的用戶控件。所以我用這種方法得到了TypeName ...

Dim strType As String = GetType(Namespace.ClassName).AssemblyQualifiedName.ToString 
Dim obj As UserControl = Activator.CreateInstance(Type.GetType(strType)) 

所以現在可以使用strType中返回的值來創建該對象的一個​​實例。上述

+0

重新開放了一個史詩般的話題......恭喜。但是我必須降低你的答案,因爲TO實際上知道Typename並想從中得到類型。順便說一句:你通過 GetType(Namespace.ClassName)引用哪種方法,如果它的Type.GetType只適用於當前正在執行的程序集或mscorlib中的類型,但作爲TO sais則不適用這些條件。 – HimBromBeere 2014-06-05 08:09:29

+2

@HimBromBeere 感謝您的投票。像你這樣的人會激怒我發表我的發現。我仍在學習發展,我只是想幫助別人。現在你希望我回答你的問題?順便說一句,我已經正確回答了這個問題。 我正在創建一個實例的類駐留在不同的項目中,因此必須使用AssemblyQualified名稱。所以請在投票前閱讀其餘的評論。 「該類型存在,它在不同的類庫中,我需要通過字符串名稱獲取它 - Omu」 – Stephan 2014-06-06 21:27:01

1

This解決方案似乎是最好的給我,但它並沒有爲我工作,所以我做了如下:

AssemblyName assemblyName = AssemblyName.GetAssemblyName(HttpContext.Current.Server.MapPath("~\\Bin\\AnotherAssembly.dll")); 
string typeAssemblyQualifiedName = string.Join(", ", "MyNamespace.MyType", assemblyName.FullName); 

Type myType = Type.GetType(typeAssemblyQualifiedName); 

的前提是你知道的組件的路徑。就我而言,我知道它是因爲它是從另一個內部項目構建的組件,並且它包含在我們項目的bin文件夾中。

萬一它很重要我使用Visual Studio 2013,我的目標.NET是4.0。這是一個ASP.NET項目,所以我通過HttpContext獲得絕對路徑。然而,絕對路徑並不是必需的,因爲它似乎從MSDN on AssemblyQualifiedNames

0

我被騙了。由於我想要創建的類型(通過名稱)都在in一個dll我控制,我只是將一個靜態方法在程序集中的dll中接受一個簡單的名稱,並從該上下文中調用type.GetType並返回結果。

最初的目的是使配置數據中的名稱可以指定類型。我已經改變了代碼,以便用戶指定要處理的格式。格式處理程序類實現了一個接口,該接口確定類型是否可以解析指定的格式。然後我使用反射來查找實現該接口的類型,並找到處理該格式的類型。所以現在配置指定了一個格式名稱,而不是一個特定的類型。反射代碼可以查看相鄰的dll和負載,因此我有一個窮人的插件體系結構。

+0

嗨,我錯誤地降低了請編輯您的回覆,以便我可以撤消它。 – coloboxp 2016-08-15 11:28:53

6

如果你的類是不是在當前assambly你必須給的qualifiedName這個代碼演示瞭如何獲取的qualifiedName類

string qualifiedName = typeof(YourClass).AssemblyQualifiedName; 

,然後你可以得到類型與qualifiedName中

Type elementType = Type.GetType(qualifiedName); 
2

確保該逗號直接在完全限定名稱後

typeof(namespace.a.b.ClassName, AssemblyName) 

由於t他不會工作

typeof(namespace.a.b.ClassName ,AssemblyName) 

我難倒了幾天就這一個

1

當我只有我使用這個類名:

Type obj = AppDomain.CurrentDomain.GetAssemblies().SelectMany(t => t.GetTypes()).Where(t => String.Equals(t.Name, _viewModelName, StringComparison.Ordinal)).First(); 
1

對我來說,一個「+」號鑰匙! 這是我的類(它是一個嵌套的一個):

namespace PortalServices 
{ 
public class PortalManagement : WebService 
{ 
    public class Merchant 
    {} 
} 
} 

,這行代碼的工作:

Type type = Type.GetType("PortalServices.PortalManagement+Merchant");