How can I use reflection or alternatives for programmatic function calls?

I start a little with Reflection. I hope it is possible to do what I would like. I work through ProjectEuler to learn the language, and I have a base class called "Problem". Each individual PE problem is a separate class, i.e. problem 16. To do my calculations, I use the following code:

using System; using Euler.Problems; using Euler.Library; namespace Euler { static class Program { [STAThread] static void Main() { Problem prob = new Problem27(); } } } 

Now I have completed 50 problems, and I want to create a loop to run them. My problem with the base class has a method that adds the problem number, response, and runtime to the text file, which is called in each default constructor of the class. I could manually change the function call for all 50, but as I continue to solve problems, this will ultimately be a lot of work.

I would rather do it programmatically. I was hoping this pseudo code would become a reality:

 for (int i = 1; i <= 50; i++) { string statement = "Problem prob = new Problem" + i + "();"; // Execute statement } 
+8
reflection c #
source share
5 answers

with reflections, you can do much nicer.

e.g. declare an interface

 interface IEulerProblem { void SolveProblem(); } 

write your classes that are derived from IEulerProblem.

then you can run all (technically) one beautiful line of code:

 Assembly.GetEntryAssembly() .GetTypes() .Where(t => typeof(IEulerProblem).IsAssignableFrom(t)) .Where(t => !t.IsInterface && !t.IsAbstract) .Select(t => Activator.CreateInstance(t) as IEulerProblem) .OrderBy(t => t.GetType().Name).ToList() .ForEach(p => p.SolveProblem()); 
+10
source share

First take a look at Get all inherited classes of an abstract class , which also applies to non-abstract classes.

Then you can simply call the method for the base class for each.

 foreach (problem p in problems) { p.MyMethod() } 
+1
source share

Yes, it is possible, you will want to read in MethodInfo.Invoke: http://msdn.microsoft.com/en-us/library/system.reflection.methodinfo.invoke.aspx

0
source share
 var problems = Assembly.GetExecutingAssembly().GetTypes() .Where(t => !t.IsAbstract && typeof(Problem).IsAssignableFrom(t)); foreach(var p in problems) { var euler = Activator.CreateInstance(p) as Problem; euler.Solve(); // ?? } 
0
source share

As one of the possible solutions, I would like to suggest creating a list of designer delegates without using reflection.
You still have to fill out the list 50 times, but only once. You will have security types, although they may indicate different constructors for each of the derived classes. Something like that:

  List<Func<Test>> tests = new List<Func<Test>>(); tests.Add(() => new Test1()); tests.Add(() => new Test2()); foreach (var constructor in tests) { Test test = constructor(); } 
0
source share

All Articles