Create and use an instance of a class whose class name is known only at run time

I have a list of class names and methods that can only be read at runtime. Is it possible to dynamically create a class like this? I am currently using C # 4.0.

+4
source share
3 answers

It’s a little unclear whether you want to determine the type at runtime and define methods against it, or if you want to instantiate an already written type and call methods on it.

Fortunately, both options are possible.

The second scenario is more likely, so you need to look at the considerations (below), but note that it involves performance related fines (and small things like “what arguments does the method” become very important).

For the first scenario, you need to look at TypeBuilder , but it is much more complicated. Another option would be CSharpCodeProvider and dynamic assembly, but then again - non-trivial for any stretch.

 using System; namespace MyNamespace { public class Foo { public void Bar() { Console.WriteLine("Foo.Bar called"); } } } class Program { static void Main() { string className = "MyNamespace.Foo, MyAssemblyName", methodName = "Bar"; Type type = Type.GetType(className); object obj = Activator.CreateInstance(type); type.GetMethod(methodName).Invoke(obj, null); } } 

To include parameters (comments), you pass object[] instead of null :

 using System; namespace MyNamespace { public class Foo { public void Bar(string value) { Console.WriteLine("Foo.Bar called: " + value); } } } class Program { static void Main() { string className = "MyNamespace.Foo, MyAssemblyName", methodName = "Bar"; Type type = Type.GetType(className); object obj = Activator.CreateInstance(type); object[] args = { "hello, world" }; type.GetMethod(methodName).Invoke(obj, args); } } 

If you make this lot (for the same method), there is a way to improve performance using a typed delegate, but that does not bring you any special prizes.

+3
source

You can use the IL emission function directly from the .Net environment to accomplish this. You will need to learn IL to dynamically generate type information at runtime - this is not for the heart.

Introduction to Creating Dynamic Types Using System.Reflection.Emit

0
source

Since I cannot answer what you ask, I will answer a few questions that you can ask.

Can I instantiate a class and call its method when both classes and methods are specified at runtime?

Of course. The easy way. Use if :

 var className = "MyClass"; var methodName = "MyMethod"; if (className == typeof(MyClass).Name) { var instance = new MyClass(); if (methodName == "MyMethod") instance.MyMethod(); if (methodName == "MyOtherMethod") instance.MyOtherMethod(); } 

Alternatively, you can use Activator.CreateInstance to instantiate the class for you.

 var className = "MyClass"; var methodName = "MyMethod"; //Get a reference to the Assembly that has the desired class. Assume that all classes that we dynamically invoke are in the same assembly as MyClass. var assembly = typeof(MyClass).Assembly; //Find the type that we want to create var type = assembly.GetTypes().FirstOrDefault(t=>t.Name == className); if(type != null) { //Create an instance of this type. var instance = Activator.CreateInstance(type); //Find the method and call it. instance.GetType().GetMethod(methodName).Invoke(instance); } 

Can I generate a class at runtime?

Yes, but it’s difficult. If you are an experienced C # programmer, know a bit of C ++ and the assembly, you should be able to get it. If not, don’t worry.

Microsoft provides a library for emitting an intermediate language code called surpose, IL.Emit . There are very few problems that guarantee the use of this method, among which are the generation of a mock object and some aspects of Injection Dependency Injection. It is likely that your problem is better solved in another way.

0
source

Source: https://habr.com/ru/post/1309280/


All Articles