tags:

views:

221

answers:

6

This is probably very easy, but I'm stumped. I would like to create a general purpose class which will be used multiple times in my program. I want this to be very lightweight and super fast.

For a very simple example in C#:

public class SystemTest
{ 
   public TestMethod(string testString)
   {
      if(testString == "blue")
      {
         RunA();
      }
      else if(testString == "red")
      {
         RunB();
      }
      else if(testString == "orange")
      {
         RunA();
      }
      else if(testString == "pink")
      {
         RunB();
      }
   }

   protected void RunA() {}
   protected void RunB() {}       
}

I want the RunA() and the RunB() to be defined and controlled by the object instancing this class. It will be completely up to the object instancing SystemTest class to figure out whatever RunA() and RunB() will be doing. How do you do this?

I don't want the instance object to always inherit this SystemTest class, and I would like it to run super quickly. The only things I'm thinking of are complex, processor intensive stuff. I know there's an easier way to do this.


Edit: Typically, which runs faster, the delegate or the interface method on the answers below?

+6  A: 

It sounds like you want an interface, like:

interface ITestable {
    void RunA();
    void RunB();
}

and you pass that in (either to the SystemTest ctor, or to TestMethod). The calling classes could (for example) implement ITestable and call TestMethod(this, someString).

Alternatively, maybe an extension method? btw, the string arg could perhaps be an enum?

public interface ITestable {
    void RunA();
    void RunB();
}
public static class SystemTest
{ 
   public static void TestMethod(this ITestable item, string testString)
   {
      if(testString == "blue")
      {
         item.RunA();
      }
      else if(testString == "red")
      {
          item.RunB();
      }
      else if(testString == "orange")
      {
          item.RunA();
      }
      else if(testString == "pink")
      {
          item.RunB();
      }
   }
}

Then the callers simply implement ITestable, and anyone can call foo.SomeMethod(color); for an instance foo.

Marc Gravell
+1 for interface...
Arjan Einbu
+8  A: 

You can:

public class SystemTest
{ 
   Action RunA;
   Action RunB;
   public SystemTest(Action a, Action b)
   {
      RunA = a;
      RunB = b;
   }
   //rest of the class
}
eglasius
A: 

If there are only limited color options like blue, red, orange and pink. You can create an enum like

public enum Color 
{
   Blue,
   Red,
   Orange,
   Pink
}

And use this enum with a switch statement with any of the solutions mention here. The compiler treats enums as integers & since you want performance. Integer comparison is more efficient than string comparisons.

switch (color)
{
case Color.Blue:
case Color.Orange: 
                   RunA();
                   break;
case Color.Red:
case Color.Pink:   RunB();
                   break;
}
AB Kolan
A: 

Another option not mentioned is changing RunA and RunB to be events instead of methods. Events in .net are reasonably lightweight and fast, and would potentially match up with your usage model without requiring the construction of a new class to define behavior for each instance/usage.

Given that you want instanced based behavior, you will need to rework this to use either delegates or events, or to pass in a single base class or interface and call methods directly on that.

Reed Copsey
A: 

Expose the RunA, RunB methods as events so any caller can attach to them. Ex.:

public class SystemTest
{ 
   public TestMethod(string testString)
   {
      if(testString == "blue")
      {
         RunA();
      }
      else if(testString == "red")
      {
         RunB();
      }
      else if(testString == "orange")
      {
         RunA();
      }
      else if(testString == "pink")
      {
         RunB();
      }
   }

   protected event Action RunA;
   protected event Action RunB;       
}
AZ
A: 

Why use a class when all you need is a data structure?

Dictionary<string, Action> MethodMap = new Dictionary<string, Action>
{
   { "red", RedMethod },
   { "blue", BlueMethod },
   { "green", GreenMethod },
   { "yellow", YellowMethod }
};

Then you don't need a class to run the method; simply

Method[key];

will do.

Robert Rossney
umm for a complete strong typing experience?
Hasan Khan