C# 从类型的部分名称获取 System.Type

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/179102/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 16:48:11  来源:igfitidea点击:

Getting a System.Type from type's partial name

c#.netreflectiontypes

提问by Mark T

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

我只想System.Typestring.

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

回答by Chris Marasti-Georg

Type type = Type.GetType("foo.bar.MyClass, foo.bar");

MSDN. Make sure the name is Assembly Qualified.

微软。确保名称为Assembly Qualified

回答by jalbert

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.

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

回答by Seibar

To create an instance of your class after you get the type, and invoke a method -

在获得类型后创建类的实例,并调用一个方法 -

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

回答by dmihailescu

Type.GetType(...)might fail sometimes if the typeofoperator can not be used.

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

Instead you can reflect on the assemblies from the current domain in order to do it.

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

check my response on this thread

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

回答by Zbigniew Wiadro

Another way to get the type from current or another assebly.

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

(Assumes that the class namespace contains its assembly):

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



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

回答by shadow

Here is a simple method for creating and initializing a new object from its name and parameters:

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

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

One example of how one might use this is to read a file containing class names [or partial class names] and parameters and then add the objects returned to a list of objects of a base type that is common to the objects created.

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

To see what your class name [or ] should look like, temporarily use something like this [if your class is named NewClass]:

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

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

回答by nawfal

It depends on which assembly the class is. If it's in mscorlibor calling assembly all you need is

这取决于类是哪个程序集。如果它在mscorlib或调用程序集,您只需要

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

But if it's referenced from some other assembly, you would need to do:

但是,如果它是从其他程序集引用的,则需要执行以下操作:

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

//or

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


If you only have the class name "MyClass", then you have to somehow get the namespace name (or both namespace name and assembly name in case it's a referenced assembly) and concat that along with the class name. Something like:

如果您只有类名“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);


If you have absolutely nothing (no preawareness of even assembly name or namespace name) but just the class name, then you can query the entire assemblies to select a matching string. But that should be a lot slower:

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

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

Note that this returns the first matching class, so need not be very accurate if you would have multiple classes with same name across assemblies/namespaces.In any case caching the values makes sense here. Slightly faster way is to assume there is one default namespace:

请注意,这将返回第一个匹配的类,因此如果跨程序集/命名空间有多个具有相同名称的类,则不需要非常准确。在任何情况下,缓存值在这里都是有意义的。稍微快一点的方法是假设有一个默认命名空间

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

But that's again an assumption that your type will have the same namespace as some other random class in the assembly; too brittle, not very good.

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



If you want classes of other domains you can get a list of all application domains, following this link.You can then do the same querying as shown above for each domain. If your assembly where the type resides isn't loaded yet, then you have to manually load it using Assembly.Load, Assembly.LoadFrometc.

如果您想要其他域的类,您可以通过此链接获取所有应用程序域的列表然后,您可以对每个域执行如上所示的相同查询。如果您的组件,其中居住类还没有加载,那么你必须使用手动加载它Assembly.LoadAssembly.LoadFrom等等。