39

I want to get a System.Type given only the type name in a string.

For instance, if I have an object:

MyClass abc = new MyClass();

I can then say:

System.Type type = abc.GetType();

But what if all I have is:

string className = "MyClass";
4

7 回答 7

43

这取决于类是哪个程序集。如果它在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”,那么您必须以某种方式获取名称空间名称(或名称空间名称和程序集名称,以防它是引用的程序集)并将其与类名连接。就像是:

//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);

如果您一无所有(甚至不知道程序集名称或命名空间名称),而只有类名,那么您可以查询整个程序集以选择匹配的字符串。但这应该慢很多

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);

但这又是一个假设,即您的类型将与程序集中的其他随机类具有相同的命名空间;太脆了,不太好。


如果您想要其他域的类,您可以通过此链接获取所有应用程序域的列表。然后,您可以对每个域执行如上所示的相同查询。如果尚未加载类型所在的程序集,则必须使用等手动加载Assembly.LoadAssembly.LoadFrom

于 2013-12-05T18:34:08.130 回答
32
Type type = Type.GetType("foo.bar.MyClass, foo.bar");

MSDN. Make sure the name is Assembly Qualified.

于 2008-10-07T15:42:24.227 回答
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]);
于 2008-10-07T16:51:08.330 回答
1
Type type = Type.GetType("MyClass");

Make sure to include the namespace. There are overloads of the method that control case-sensitivity and whether an exception is thrown if the type name isn't found.

于 2008-10-07T15:42:32.043 回答
1

从当前或其他组件中获取类型的另一种方法。

(假设类命名空间包含它的程序集):


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;
}
于 2013-01-31T11:59:33.713 回答
0

Type.GetType(...)如果无法使用运算符,有时可能会失败typeof

相反,您可以反映当前域中的程序集以执行此操作。

检查我在这个线程上的回复

于 2011-09-02T16:30:21.560 回答
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;
    }

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

要查看您的类名 [或 ] 应该是什么样子,请暂时使用类似这样的内容 [如果您的类名为 NewClass]:

    string z = (new NewClass(args)).GetType().FullName;
于 2013-09-25T06:10:38.633 回答