开发者

In C#, how can I pass a method from another class using Func<T>?

开发者 https://www.devze.com 2023-04-04 05:35 出处:网络
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 ca

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.DoSometh开发者_StackOverflowing3:
                    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
                }
            }
        }
    }


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


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;  
    }
}
0

精彩评论

暂无评论...
验证码 换一张
取 消