Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I use reflection or alternative to create function calls programatically?

Tags:

c#

reflection

I'm a bit of a novice with Reflection. I'm hoping that it's possible to do what I'd like it to. I've been working through ProjectEuler to learn the language, and I have a base class called Problem. Every individual PE problem is a separate class, i.e. Problem16. To run 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();
        }
    }
}

I have completed 50 problems now, and I want to create a loop to run them all. My base class Problem has a method that appends to a text file the problem number, the answer, and the execution time that's called in each class's default constructor. I could manually change the function call for all 50, but as I continue to complete problems, this will end up being a lot of work.

I'd much rather do it programatically. I was hoping for this pseudocode become a reality:

for (int i = 1; i <= 50; i++)
{
    string statement = "Problem prob = new Problem" + i + "();";
    // Execute statement
}
like image 862
wmaynard Avatar asked Dec 21 '12 17:12

wmaynard


2 Answers

with reflections, you can do much nicer things.

for example, declare an interface

interface IEulerProblem 
{
   void SolveProblem();
}

write your classes which are derived from IEulerProblem.

then you can run all within (technically) one nice 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());
like image 152
user287107 Avatar answered Oct 15 '22 05:10

user287107


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

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

foreach (problem p in problems)
{
  p.MyMethod()
}
like image 32
Erik Philips Avatar answered Oct 15 '22 04:10

Erik Philips