C# - How to check if namespace, class or method exists in C#?

57,723

Solution 1

You can use Type.GetType(string) to reflect a type. GetType will return null if the type could not be found. If the type exists, you can then use GetMethod, GetField, GetProperty, etc. from the returned Type to check if the member you're interested in exists.

Update to your example:

string @namespace = "MyNameSpace";
string @class = "MyClass";
string method= "MyMEthod";

var myClassType = Type.GetType(String.format("{0}.{1}", @namespace, @class));
object instance = myClassType == null ? null : Activator.CreateInstance(myClassType); //Check if exists, instantiate if so.
var myMethodExists = myClassType.GetMethod(method) != null;

Console.WriteLine(myClassType); // MyNameSpace.MyClass
Console.WriteLine(myMethodExists); // True

This is the most efficient and preferred method, assuming the type is in the currently executing assembly, in mscorlib (not sure how .NET Core affects this, perhaps System.Runtime instead?), or you have an assembly-qualified name for the type. If the string argument you pass to GetType does not satisfy those three requirements, GetType will return null (assuming there isn't some other type that accidentally does overlap those requirements, oops).


If you don't have the assembly qualified name, you'll either need to fix your approach so you do or perform a search, the latter being potentially much slower.

If we assume you do want to search for the type in all loaded assemblies, you can do something like this (using LINQ):

var type = (from assembly in AppDomain.CurrentDomain.GetAssemblies()
            from type in assembly.GetTypes()
            where type.Name == className
            select type);

Of course, there may be more to it than that, where you'll want to reflect over referenced assemblies that may not be loaded yet, etc.

As for determining the namespaces, reflection doesn't export those distinctly. Instead, you'd have to do something like:

var namespaceFound = (from assembly in AppDomain.CurrentDomain.GetAssemblies()
from type in assembly.GetTypes()
where type.Namespace == namespace
select type).Any()

Putting it all together, you'd have something like:

var type = (from assembly in AppDomain.CurrentDomain.GetAssemblies()
                from type in assembly.GetTypes()
                where type.Name == className && type.GetMethods().Any(m => m.Name == methodName)
                select type).FirstOrDefault();

if (type == null) throw new InvalidOperationException("Valid type not found.");

object instance = Activator.CreateInstance(type);

Solution 2

You can resolve a Type from a string by using the Type.GetType(String) method. For example:

Type myType = Type.GetType("MyNamespace.MyClass");

You can then use this Type instance to check if a method exists on the type by calling the GetMethod(String) method. For example:

MethodInfo myMethod = myType.GetMethod("MyMethod");

Both GetType and GetMethod return null if no type or method was found for the given name, so you can check if your type/method exist by checking if your method call returned null or not.

Finally, you can instantiate your type using Activator.CreateInstance(Type) For example:

object instance = Activator.CreateInstance(myType);

Solution 3

One word: Reflection. Except for Namespaces, you'll have to parse those out of the Type names.

EDIT: Strike that - for namespaces you'll have to use the Type.Namespace property to determine which namespace each class belongs to. (See HackedByChinese response for more information).

Share:
57,723
kazinix
Author by

kazinix

Updated on July 16, 2020

Comments

  • kazinix
    kazinix almost 4 years

    I have a C# program, how can I check at runtime if a namespace, class, or method exists? Also, how to instantiate a class by using it's name in the form of string?

    Pseudocode:

    string @namespace = "MyNameSpace";
    string @class = "MyClass";
    string method= "MyMEthod";
    
    var y = IsNamespaceExists(namespace);
    var x = IsClassExists(@class)? new @class : null; //Check if exists, instantiate if so.
    var z = x.IsMethodExists(method);
    
  • M.Babcock
    M.Babcock over 12 years
    And how would you determine if a namespace exists with your examples?
  • moribvndvs
    moribvndvs over 12 years
    Updated my answer. Check the second code example. We enumerate each loaded assembly, and each type in each assembly, and look for any type that has desired namespace name.
  • moribvndvs
    moribvndvs over 12 years
    If you want to check that the namespace is valid, the class name is valid, and the class has a method, you can do that all in one shot with the third code example. just change where type.Name == className to something like where type.FullName == string.Format("{0}.{1}", namespace, className) && type.GetMethods().Any(m => m.Name == methodName). Also, I made a mistake in those examples by leaving out the select part of the statement. corrected.
  • M.Babcock
    M.Babcock over 12 years
    +1 Nice example. I hadn't even realized that there was a Type.Namespace property...
  • moribvndvs
    moribvndvs over 12 years
    You could do this with nested foreach loops; i just went with LINQ because it's easier. I can provide such an example if you'd prefer.
  • Cerena
    Cerena about 9 years
    This is a much quicker and more concise answer than the one marked as correct above. Spinning every type in every assembly is painfully slow. If you include all the System assemblies, that might be a 10,000 iteration loop.
  • Latheesan
    Latheesan about 6 years
    This is what I was after, short and simple.
  • derHugo
    derHugo over 5 years
    Reflection URL is down unfortunately
  • M.Babcock
    M.Babcock about 5 years
    Fixed broken reflection link.