Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting a System.Type from type's partial name

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"; 
like image 295
Mark T Avatar asked Oct 07 '08 15:10

Mark T


People also ask

How to Get type by name in C#?

To load a type by name, you either need it's full name (if the assembly has already been loaded into the appdomain) or its Assembly Qualified name. The full name is the type's name, including the namespace. You can get that by calling Type. GetType(typeof(System.

What is the return type of GetType in C#?

C# String GetType() The C# GetType() method is used to get type of current object. It returns the instance of Type class which is used for reflection.

What is typeof in C#?

The C# typeof operator ( GetType operator in Visual Basic) is used to get a Type object representing String. From this Type object, the GetMethod method is used to get a MethodInfo representing the String. Substring overload that takes a starting location and a length.


2 Answers

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.

like image 68
nawfal Avatar answered Oct 04 '22 07:10

nawfal


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

MSDN. Make sure the name is Assembly Qualified.

like image 27
Chris Marasti-Georg Avatar answered Oct 04 '22 09:10

Chris Marasti-Georg