Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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); 
like image 953
dpp Avatar asked Dec 14 '11 04:12

dpp


1 Answers

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); 
like image 86
moribvndvs Avatar answered Sep 28 '22 05:09

moribvndvs