Type.GetType("namespace.a.b.ClassName") returns null
Asked Answered
G

18

278

This code:

Type.GetType("namespace.a.b.ClassName")

returns null.

I have in the usings:

using namespace.a.b;

The type exists, it's in a different class library, and I need to get it by it's name given as string.

Glycerinate answered 1/12, 2009 at 9:53 Comment(1)
See this #442180 for info on how to get the assembly qualified name.Diametrically
I
347

Type.GetType("namespace.qualified.TypeName") only works when the type is found in either mscorlib.dll or the currently executing assembly.

If neither of those things are true, you'll need an assembly-qualified name:

Type.GetType("namespace.qualified.TypeName, Assembly.Name")
Inebriate answered 1/12, 2009 at 9:55 Comment(4)
Instead of using an assembly-qualified name you can load the assembly by name – Assembly a = Assembly.Load("SomeLibrary"); – and then load the type by name from the assembly – Type t = a.GetType("namespace.a.b.ClassName");.Excurved
Perhaps you could like typeof(SomeTypeInThatAssembly).Assembly.GetTypes().Where((t) => t.FullName == youFullName); may save some hassle, eventuallyIncalculable
Is it correct that you must specify namespace.qualified.TypeName and not only TypeName with this approach?Topcoat
What if the Type is from generated wsdl from the server? This does not work for me. Do you have any idea why its not working? ThanksFlamethrower
C
198

You can also get the type without assembly qualified name but with the dll name also, for example:

Type myClassType = Type.GetType("TypeName,DllName");

I had the same situation and it worked for me. I needed an object of type "DataModel.QueueObject" and had a reference to "DataModel" so I got the type as follows:

Type type = Type.GetType("DataModel.QueueObject,DataModel");

The second string after the comma is the reference name (dll name).

Chastain answered 24/6, 2011 at 8:15 Comment(5)
Is this a 'trick' or an actual method? I can't find this in documentation -_- . By the way, it ends my 1 week suffer! thanksInterpret
This is a much cleaner solution, I'd love to see if there are any pitfalls because of this.Fugato
The form used in this answer is also a fully qualified type name according to the MSDN grammar (so it is not a trick). The form is NamespaceTypeName, AssemblyNameSpec where AssemblyNameSpec is the identifier of the assembly without any properties. Even though this answer is essentially the same as the accepted I assume that some people prefer this because it does away with some of the "noise" that the assembly properties introduce (e.g. Version, Culture PublicKeyToken). Fortunately, the properties are optional.Ramonramona
For nested types, you may need to do something like AtlasKernelBusinessModel.AtlasConstants+ClaimCoverage+Status,AtlasKernelBusinessModelRoundlet
Thanks, that solved my problem. If you are trying to get TypeName from another assembly (say your solution has 2 projects and you are trying to get type of a class located in one project, from the other project, then you need to provide fully qualified class name and assembly name as comma separated as @AsafPala suggested. See here same question I had and solution/explanation I added #54681889Shocking
P
97

Try this method.

public static Type GetType(string typeName)
{
    var type = Type.GetType(typeName);
    if (type != null) return type;
    foreach (var a in AppDomain.CurrentDomain.GetAssemblies())
    {
        type = a.GetType(typeName);
        if (type != null)
            return type;
    }
    return null;
}
Petulia answered 4/8, 2012 at 18:25 Comment(2)
This is what actually worked for me. I had to tweak by adding a substring trim before the foreach loop, however, because I passed in an assembly-qualified name, and Assembly.GetType() only works if you exclude the assembly information.Treacy
Doesn't work for UWP because AppDomain isn't supported. Not sure of any alternatives.Tennyson
G
31

If the assembly is part of the build of an ASP.NET application, you can use the BuildManager class:

using System.Web.Compilation
...
BuildManager.GetType(typeName, false);
Goodly answered 5/12, 2012 at 18:49 Comment(2)
This is a fantastic answer and should be higher up on the page. Works like a charm and is dead-simple compared to the old way of getting the assembly's qualified type name.Allonym
@Graham it's old but it's essential and will never become obsolete or logically wrong. Each Type is contained in a specific assembly. We cannot identify a type with just its name without knowing about its container. Multiple types having one same name are possible. Although in some specific scope we do know for sure that a Type name is unique. Even the assembly itself needs a strong name (to be uniquely ensured) in many cases.Boltonia
C
27
Dictionary<string, Type> typeCache;
...
public static bool TryFindType(string typeName, out Type t) {
    lock (typeCache) {
        if (!typeCache.TryGetValue(typeName, out t)) {
            foreach (Assembly a in AppDomain.CurrentDomain.GetAssemblies()) {
                t = a.GetType(typeName);
                if (t != null)
                    break;
            }
            typeCache[typeName] = t; // perhaps null
        }
    }
    return t != null;
}
Clairvoyance answered 1/12, 2009 at 11:27 Comment(2)
this looks great, but what about generics using other assembly types?Gladwin
@DemetrisLeptos (I know the comment is old - but other people may still be interested): use int index = typeName.IndexOf('`'); if (index > 0) { typeName = _typeName.Substring(0, index + 2); } Note that the T of the generic type is stripped off.Stlaurent
M
21

if your class is not in current assambly you must give qualifiedName and this code shows how to get qualifiedname of class

string qualifiedName = typeof(YourClass).AssemblyQualifiedName;

and then you can get type with qualifiedName

Type elementType = Type.GetType(qualifiedName);
Muse answered 21/3, 2017 at 13:42 Comment(1)
Am I missing something, don't you already have elementType if you do typeof(YourClass)?Golly
J
17

As Type.GetType(String) need the Type.AssemblyQualifiedName you should use Assembly.CreateQualifiedName(String, String).

string typeName = "MyNamespace.MyClass"; // Type.FullName
string assemblyName = "MyAssemblyName"; // MyAssembly.FullName or MyAssembly.GetName().Name
string assemblyQualifiedName = Assembly.CreateQualifiedName(assemblyName , typeName);
Type myClassType = Type.GetType(assemblyQualifiedName);

The Version, Culture and PublicKeyToken are not required for assemblyName that's why you can use MyAssembly.GetName().Name.

About Type.GetType(String) :

If the type is in the currently executing assembly or in Mscorlib.dll, it is sufficient to supply the type name qualified by its namespace.

Jasisa answered 14/5, 2018 at 16:8 Comment(0)
B
11

When I have only the class name I use this:

Type obj = AppDomain.CurrentDomain.GetAssemblies().SelectMany(t => t.GetTypes()).Where(t => String.Equals(t.Name, _viewModelName, StringComparison.Ordinal)).First();
Blither answered 11/8, 2017 at 7:25 Comment(0)
C
8

If it's a nested Type, you might be forgetting to transform a . to a +

Regardless, typeof( T).FullName will tell you what you should be saying

EDIT: BTW the usings (as I'm sure you know) are only directives to the compiler at compile time and cannot thus have any impact on the API call's success. (If you had project or assembly references, that could potentially have had influence - hence the information isnt useless, it just takes some filtering...)

Cailean answered 1/12, 2009 at 9:57 Comment(2)
Oh my! Do you know where this "+"-syntax is explained?Loupgarou
Protectorone I learnt it from amazon.com/Essential-NET-Common-Language-Runtime/dp/0201734117 IIRC, but that's a bit dated. Can I recommend amazon.com/CLR-via-4th-Developer-Reference/dp/0735667454/… as a unerringly useful book for all .NET devs + includes this? Bottom line is that for Types, the CLR only has the namespace and the name - a nested type is not directly addressable. Hence a language, if it has a nested type concept gets to do what it needs (though in general most langs use a + separator)Cailean
I
5

I am opening user controls depending on what user controls the user have access to specified in a database. So I used this method to get the TypeName...

Dim strType As String = GetType(Namespace.ClassName).AssemblyQualifiedName.ToString
Dim obj As UserControl = Activator.CreateInstance(Type.GetType(strType))

So now one can use the value returned in strType to create an instance of that object.

Istanbul answered 17/5, 2014 at 20:59 Comment(3)
re-opening an epic-old topic... congratulations. However I have to downvote your answer because the TO actually knows the Typename and wants to get the type from it. Btw.: which method do you reference by <c>GetType(Namespace.ClassName)</c>, if its Type.GetType it´ll only work on types that are within your current executing assembly or mscorlib, but as TO sais none of these conditions applies.Driver
@HimBromBeere Thanks for the down vote. It is people like you that demotivate me to post my findings. I am still learning development and I am just trying to help others. And now you expect me to answer your question? By the way, I have answered the question correctly. The class that I was creating an instance of resides in a different project and one has to use an AssemblyQualified name because of that. So please read the rest of the comments before downvoting. "the type exists, it's in a different class library, and i need to get it by string name – Omu"Istanbul
@Istanbul - Welcome to StackOverlow - its not a toxic place really. Honestly.Hamamelidaceous
I
4

If the assembly is referenced and the Class visible :

typeof(namespace.a.b.ClassName)

GetType returns null because the type is not found, with typeof, the compiler may help you to find out the error.

Incongruity answered 1/12, 2009 at 9:55 Comment(1)
the type exists, it's in a different class library, and i need to get it by string nameGlycerinate
L
4

Try using the full type name that includes the assembly info, for example:

string typeName = @"MyCompany.MyApp.MyDomain.MyClass, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null";
Type myClassType = Type.GetType(typeName);

I had the same situation when I was using only the the namesspace.classname to get the type of a class in a different assembly and it would not work. Only worked when I included the assembly info in my type string as shown above.

Lacteal answered 13/4, 2011 at 18:42 Comment(0)
A
2

Make sure that the comma is directly after the fully qualified name

typeof(namespace.a.b.ClassName, AssemblyName)

As this wont work

typeof(namespace.a.b.ClassName ,AssemblyName)

I was stumped for a few days on this one

Antho answered 24/3, 2017 at 0:47 Comment(0)
D
2

For me, a "+" was the key! This is my class(it is a nested one) :

namespace PortalServices
{
public class PortalManagement : WebService
{
    public class Merchant
    {}
}
}

and this line of code worked:

Type type = Type.GetType("PortalServices.PortalManagement+Merchant");
Digger answered 16/10, 2017 at 7:11 Comment(0)
C
1

Here's what worked for me - I didn't want to build long library names, nor did I want to manually load libraries, so I programmatically found the library instead. Basically, I'm using the short name to find a match in GetTypes(), then I'm using that found construct to access the long name in the assembly. I really liked Marchino's LINQ implementation above, and wanted that to work for me, but I'm not good enough to work with two variables in LINQ statement :-)

    public static Type GetType(string type)
    {
        Type t = null;
        foreach (var a in AppDomain.CurrentDomain.GetAssemblies())
        {
            foreach (var s in a.GetTypes())
            {
                if (s.Name == type)
                {
                    t = a.GetType(s.FullName); 
                    if (t != null) return t;
                }
            }
        }

        return t;
    }
Correna answered 27/4, 2023 at 16:0 Comment(0)
C
0

This solution above seems to be the best to me, but it didn't work for me, so I did it as follows:

AssemblyName assemblyName = AssemblyName.GetAssemblyName(HttpContext.Current.Server.MapPath("~\\Bin\\AnotherAssembly.dll"));
string typeAssemblyQualifiedName = string.Join(", ", "MyNamespace.MyType", assemblyName.FullName);

Type myType = Type.GetType(typeAssemblyQualifiedName);

The precondition is that you know the path of the assembly. In my case I know it because this is an assembly built from another internal project and its included in our project's bin folder.

In case it matters I am using Visual Studio 2013, my target .NET is 4.0. This is an ASP.NET project, so I am getting absolute path via HttpContext. However, absolute path is not a requirement as it seems from MSDN on AssemblyQualifiedNames

Carabiniere answered 27/11, 2015 at 10:4 Comment(0)
B
0

I cheated. Since the types I want to create (by name) are all in In a dll I control, I just put a static method in the dll in the assembly that takes a simple name, and calls type.GetType from that context and returns the result.

The original purpose was so that the type could be specified by name in configuration data. I've since change the code so that the user specified a format to process. The format handler classes implement a interface that determines if the type can parse the specified format. I then use reflection to find types that implement the interface, and find one that handles the format. So now the configuration specifies a format name, a not a specific type. The reflection code can look at adjacent dlls and load, them so I have a sort poor man's plug-in architecture.

Barfuss answered 15/6, 2016 at 17:34 Comment(1)
Hi, I've downvoted by mistake, please edit your reply so I can undo it.Osrock
E
0

Very late reply, but if anyone is dealing with this a decade later:

There is a very, very small chance that your class in Visual Studio has a Build Action set to "Content" instead of "Compile".

Click on your class in Solution Explorer, then look at the properties.

Check that Build Action is "Compile", not "Content".

Ehlers answered 17/7, 2022 at 0:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.