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";
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";
这取决于类是哪个程序集。如果它在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.Load它Assembly.LoadFrom。
Type type = Type.GetType("foo.bar.MyClass, foo.bar");
MSDN. Make sure the name is Assembly Qualified.
在获取类型后创建类的实例并调用方法 -
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]);
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.
从当前或其他组件中获取类型的另一种方法。
(假设类命名空间包含它的程序集):
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;
}
下面是一个从名称和参数创建和初始化新对象的简单方法:
// 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;