从全名创建 C# 类型

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1392763/
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-06 16:00:10  来源:igfitidea点击:

Creating C# Type from full name

c#assembliestypes

提问by Adi Barda

I'm trying to get a Type object from type full name i'm doing the folowing:

我正在尝试从类型全名中获取类型对象,我正在执行以下操作:

Assembly asm = Assembly.GetEntryAssembly();  
string toNativeTypeName="any type full name";
Type t = asm.GetType(toNativeTypeName);

I get null, why?

我得到空值,为什么?

the assembly is my executable (.net executable) and the type name is: System.Xml.XmlNode

程序集是我的可执行文件(.net 可执行文件),类型名称是:System.Xml.XmlNode

回答by Jon Skeet

Well, if that really is the type's full name (i.e. including namespace) and it's in that assembly, then it should work. Could you give an example where it doesn't? As you're using Assembly.GetTyperather than Type.GetTypeyou shouldn'tinclude the assembly name in the type name.

好吧,如果这确实是类型的全名(即包括命名空间)并且它在该程序集中,那么它应该可以工作。你能举一个没有的例子吗?当您使用Assembly.GetType而不是Type.GetType不应该在类型名称中包含程序集名称。

Note that the name for a generic type isn't what you might expect it to be. For instance, you'd use:

请注意,泛型类型的名称不是您所期望的。例如,你会使用:

assembly.GetType("System.Collections.Generic.List`1");

to get the generic list type, then use Type.MakeGenericTypeto provide type arguments.

获取泛型列表类型,然后用于Type.MakeGenericType提供类型参数。

Of course, that's only relevant when the type is generic. If that's not the problem, I'd double check that the type really is in your entry assembly.

当然,这仅在类型为泛型时才相关。如果这不是问题,我会仔细检查该类型是否确实在您的入口程序集中。

EDIT: Oh, and be aware that nested types will be "Container+Nested" rather than "Container.Nested" if that's relevant...

编辑:哦,请注意,如果相关,嵌套类型将是“Container+Nested”而不是“Container.Nested”...

回答by Rune Grimstad

Your type name is most probably wrong. If you create a reference to the type in code and then check its Type.FullNameproperty you will see how the name of the type should look.

您的类型名称很可能是错误的。如果您在代码中创建对类型的引用,然后检查其Type.FullName属性,您将看到类型名称的外观。

Also you could try the Type.GetTypemethod and see what it returns. Maybe your type isn't in that assembly at all?

您也可以尝试该Type.GetType方法并查看它返回的内容。也许你的类型根本不在那个程序集中?

Edit: It turns out that I was wrong about using the Type.FullName property. If you use the Type.AssemblyQualifiedName property you will get the fully qualified name that can be used by Type.GetType.

编辑:事实证明我使用 Type.FullName 属性是错误的。如果您使用 Type.AssemblyQualifiedName 属性,您将获得可供 Type.GetType 使用的完全限定名称。

For System.Xml.XmlNode you get the following name: System.Xml.XmlElement, System.Xml, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089

对于 System.Xml.XmlNode,您将获得以下名称: System.Xml.XmlElement, System.Xml, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089

回答by Wael Dalloul

why you are defining assembly to use get type!, also you need to put namespace

为什么要定义程序集以使用 get 类型!,还需要放置命名空间

string toNativeTypeName = "System.Int32";
Type t = Type.GetType(toNativeTypeName );
MessageBox.Show(t.FullName);

回答by justind

I came across this thread and noticed that the original question has not quite been answered. I could be wrong, but in reading the question I think the authors intent was to be able to simply get a Type from an Assembly that is referenced or part of your application.

我遇到了这个线程,并注意到原来的问题还没有得到完全回答。我可能是错的,但在阅读这个问题时,我认为作者的意图是能够简单地从引用或应用程序的一部分的程序集中获取类型。

Here's what I did to solve that problem.

这是我为解决该问题所做的工作。

public static Type GetTypeFromFullName(string fullClassName)
{
    AssemblyPartCollection parts = Deployment.Current.Parts;

    foreach (var part in parts)
    {
        Uri resUri = new Uri(part.Source, UriKind.Relative);
        Stream resStream = Application.GetResourceStream(resUri).Stream;
        Assembly resAssembly = part.Load(resStream);
        Type tryType = resAssembly.GetType(fullClassName, false);
        if (tryType != null)
            return tryType;
    }

    return null;
}

回答by Torbj?rn Nomell

See my suggestion below, only looping business namespace for speed

请参阅下面我的建议,仅循环业务命名空间以提高速度

private static Type GetBusinessEntityType(string typeName)
{
    Debug.Assert(typeName != null);

    List<System.Reflection.Assembly> assemblies = AppDomain.CurrentDomain.GetAssemblies()
        .Where(a => a.FullName.StartsWith("AF.BusinessEntities")).ToList();

    foreach (var assembly in assemblies)
    {
        Type t = assembly.GetType(typeName, false);
        if (t != null)
            return t;
    }
    throw new ArgumentException(
        "Type " + typeName + " doesn't exist in the current app domain");
}

Here's another way to do it:

这是另一种方法:

Type t = System.Web.Compilation.BuildManager.GetType("the.type", true, false);

Use reflector to see how it's done, at least for fun :)

使用反射器查看它是如何完成的,至少是为了好玩:)