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";
nawfal
  • 70,104
  • 56
  • 326
  • 368
Mark T
  • 3,464
  • 5
  • 31
  • 45
  • possible duplicate of [Avoid giving namespace name in Type.GetType()](http://stackoverflow.com/questions/9273629/avoid-giving-namespace-name-in-type-gettype) – Fr33dan Aug 18 '14 at 14:27
  • @Fr33dan, Circular loop? The mentioned possible [original](http://stackoverflow.com/questions/9273629/avoid-giving-namespace-name-in-type-gettype) mentions [this question](http://stackoverflow.com/questions/179102/getting-a-system-type-from-types-partial-name) as possible original (see [comment](http://stackoverflow.com/questions/9273629/avoid-giving-namespace-name-in-type-gettype#comment39575691_9273629))? :) – publicgk Dec 11 '14 at 04:45
  • @publicgk I was actually trying to flag it for a merge with that question since they are the same but that question and both have good answers. See [this meta question](http://meta.stackoverflow.com/q/269080/1111886). I did it wrong apparently and gave up, then someone came in later and decided this was the duplicate since the other was older question. – Fr33dan Dec 11 '14 at 17:00

7 Answers7

43

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

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:

//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.LoadFrom etc.

Community
  • 1
  • 1
nawfal
  • 70,104
  • 56
  • 326
  • 368
  • Note that searching for a type by name only, across all loaded assemblies, can open up a security hole in your application - should a malicious actor be able to introduce an assembly containing a class with the same name and inheritance hierarchy as the one you're searching for. – Ian Kemp Jun 28 '19 at 07:43
32
Type type = Type.GetType("foo.bar.MyClass, foo.bar");

MSDN. Make sure the name is Assembly Qualified.

Chris Marasti-Georg
  • 34,091
  • 15
  • 92
  • 137
2

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]);
Seibar
  • 68,705
  • 38
  • 88
  • 99
1

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;
}
Chris W
  • 1,562
  • 20
  • 27
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.

jalbert
  • 3,047
  • 2
  • 20
  • 21
0

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]:

    string z = (new NewClass(args)).GetType().FullName;
shadow
  • 89
  • 1
  • 4
0

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

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

check my response on this thread

Community
  • 1
  • 1
dmihailescu
  • 329
  • 4
  • 4