2009-12-01 56 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");