2008-10-07 44 views
31

我想要得到一个System.Type只给出string中的类型名称。从类型的部分名称中获取System.Type

举例来说,如果我有一个对象:

MyClass abc = new MyClass(); 

然后我就可以说:

System.Type type = abc.GetType(); 

但是,如果所有我有是什么:

string className = "MyClass"; 
+0

[避免在Type.GetType()中给出命名空间名称(http:// stackoverflow .com/questions/9273629/avoid-giving-namespace-name-in-type-gettype) – Fr33dan 2014-08-18 14:27:46

+0

@ Fr33dan,循环?提到的可能[原创](http://stackoverflow.com/questions/9273629/avoid-giving-namespace-name-in-type-gettype)提到[这个问题](http://stackoverflow.com/questions/179102/getting-a-system-type-from-types-partial-name)尽可能原创(参见[comment](http://stackoverflow.com/questions/9273629/avoid-giving-namespace-name-in-type-将gettype#comment39575691_9273629))? :) – publicgk 2014-12-11 04:45:56

+0

@publicgk我实际上是试图标记它与该问题的合并,因为它们是相同的,但是这个问题,两者都有很好的答案。看[这个元问题](http://meta.stackoverflow.com/q/269080/1111886)。我做了错误显然放弃了,然后有人进来后,并认为这是重复的,因为另一个更老的问题。 – Fr33dan 2014-12-11 17:00:33

回答

2
Type type = Type.GetType("MyClass"); 

确保包含名称空间。有控制区分大小写的方法的重载以及如果未找到类型名称,是否引发异常。

2

要你得到的类型后,创建类的实例,并调用一个方法 -

Type type = Type.GetType("foo.bar.MyClass, foo.bar"); 
object instanceObject = System.Reflection.Activator.CreateInstance(type); 
type.InvokeMember(method, BindingFlags.InvokeMethod, null, instanceObject, new object[0]); 
0

Type.GetType(...)如果typeof操作者不能使用可能有时会失败。

相反,您可以反思当前域中的程序集以完成它。

检查我的this thread

1

的另一种方式,从当前或其他获得类型assebly响应。

(假定该类命名空间包含其组件):


public static Type GetType(string fullName) 
{ 
    if (string.IsNullOrEmpty(fullName)) 
     return null; 
    Type type = Type.GetType(fullName); 
    if (type == null) 
    { 
     string targetAssembly = fullName; 
     while (type == null && targetAssembly.Length > 0) 
     { 
      try 
      { 
       int dotInd = targetAssembly.LastIndexOf('.'); 
       targetAssembly = dotInd >= 0 ? targetAssembly.Substring(0, dotInd) : ""; 
       if (targetAssembly.Length > 0) 
        type = Type.GetType(fullName + ", " + targetAssembly); 
      } 
      catch { } 
     } 
    } 
    return type; 
} 
0

下面是用于创建和从它的名称和参数初始化一个新的对象的简单方法:

// Creates and initializes a new object from its name and parameters 
    public Object CreateObjectByName(string name, params Object[] args) 
    { 
     string s = "<prefix>" + name; // case sensitive; Type.FullName 
     Type type = Type.GetType(s); 
     Object o = System.Activator.CreateInstance(type, args); 
     return o; 
    } 

如何使用它的一个例子是读取包含类名[或部分类名]和参数的文件,然后将返回的对象添加到通用基本类型的对象列表中n创建的对象。

要查看你的类名[或]应该是什么样子,暂时使用这样的事情[如果你的类被命名的NewClass]:

string z = (new NewClass(args)).GetType().FullName; 
33

这取决于其装配的类。如果它在mscorlib或调用组件的所有你需要的是

Type type = Type.GetType("namespace.class"); 

但是,如果它从其他组件引用,你需要做的:

Assembly assembly = typeof(SomeKnownTypeInAssembly).Assembly; 
Type type = assembly.GetType("namespace.class"); 

//or 

Type type = Type.GetType("namespace.class, assembly"); 

如果你只有类名“MyClass”,那么你必须以某种方式获得命名空间名称(或者是名称空间名称和程序集名称,以防万一它是引用的程序集)以及concat和类名称。喜欢的东西:

//if class is in same assembly 
var namespace = typeof(SomeKnownTypeInNamespace).Namespace; 
Type type = Type.GetType(namespace + "." + "MyClass"); 


//or for cases of referenced classes 
var assembly = typeof(SomeKnownTypeInAssembly).Assembly; 
var namespace = typeof(SomeKnownTypeInNamespace).Namespace; 
Type type = assembly.GetType(namespace + "." + "MyClass"); 
//or 
Type type = Type.GetType(namespace + "." + "MyClass" + ", " + assembly.GetName().Name); 

如果你绝对没有什么,但只是在类名,然后你就可以查询整个组件来选择匹配的字符串(不连集名称或命名空间名称preawareness)。 但应该是慢了很多

Type type = AppDomain.CurrentDomain.GetAssemblies() 
            .SelectMany(x => x.GetTypes()) 
            .FirstOrDefault(x => x.Name == "MyClass"); 

注意这返回第一个匹配类,所以不需要很准确,如果你有多个教学班,跨组件/命名空间相同的名称。在任何情况下缓存值都是有意义的。 稍快的方式是假设有一个默认的命名空间

Type type = AppDomain.CurrentDomain.GetAssemblies() 
            .Select(a => new { a, a.GetTypes().First().Namespace }) 
            .Select(x => x.a.GetType(x.Namespace + "." + "MyClass")) 
            .FirstOrDefault(x => x != null); 

但是,这又是一个假设,即你的类型将有相同的命名空间中装配一些其他随机类;太脆弱,不太好。


如果你想其他领域类,你可以得到所有的应用程序域的列表,下面this link.那么你可以做如上图所示,每个域相同的查询。如果您的程序集所在类型尚未加载,则必须使用Assembly.LoadAssembly.LoadFrom等手动加载它。