2

I have a state machine that needs to call a different method on each object from a List of objects depending on the state I'm in. Basically I'm trying to refactor the code that has a loop in each case statement of my state machine so that it looks like the code below. However I cannot seem to figure out how to pass the relevant method to my refactored function (not to mention I then don't know how to call it on each item)

Any help would be appreciated.

Here's the example code:

 public class MyOtherType { public bool Method1() { return false; } public bool Method2() { return false; } public bool Method3() { return false; } public bool Method4() { return false; } } public class MyType { public enum MyState { DoSomething1, DoSomething2, DoSomething3, DoSomething4 } private MyState State = MyState.DoSomething1; List<MyOtherType> MyListOfObjects = new List<MyOtherType>() { new MyOtherType(), new MyOtherType() }; private void StateMachine() { switch (State) { case MyState.DoSomething1: //How do I pass this in? Do I need to set it up differnetly? Process(() => MyOtherType.Method1()); break; case MyState.DoSomething2: Process(() => MyOtherType.Method2); break; case MyState.DoSomething3: Process(() => MyOtherType.Method3); break; case MyState.DoSomething4: Process(() => MyOtherType.Method4); break; } } private void Process(Func<bool> method) { foreach (MyOtherType item in MyListOfObjects) { //How do I call the method on each item? if (item.method()) { //Do something } } } } 
1
  • This is more of a design issue rather than an issue with Func<T> in my opinion. Commented Sep 9, 2011 at 10:31

2 Answers 2

2

I would suggest to get rid of such switch blocks and decouple each specific method from a state by introducing flexible map of strategy per state so it could be easily changed or even injected:

IDictionary<MyState, Func<bool>> strategyMap; 

1) Fill it in

 // if idea is to access methods without instance of MyOtherType - // make all methods and class itself static so you can access it // like MyOtherType.Method1 strategyMap = new Dictionary<MyState, Func<bool>>(); strategyMap.Add(MyState.DoSomething1, myOtherTypeInstance.Method1); 

2) Call appropriate strategy depends on state instead of switch(State)

 if (starategyMap.ContainsKey(State)) { // pass in an associated strategy Process(starategyMap[State]); } 

Feel free to ask in case of any questions

Sign up to request clarification or add additional context in comments.

1 Comment

Excellent idea, though in my real code I may have other processing in a given state. Still, this answer will enable me to refactor as desired so thanks!
0

One possible solution is to make the methods static and take the class reference they shall operate on as a parameter:

public class MyOtherType { public static bool Method1(MyOtherType instance) { return instance == null; } } 

1 Comment

Yes I had considered this but since I was trying to refactor a repetitive loop that only varied by method call, it seemed counter productive to generate numerous additional static methods just for this purpose. However it is still a valid suggestion, thank you.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.