В C #, как я могу передать метод из другого класса, используя Func <T>? - PullRequest
2 голосов
/ 09 сентября 2011

У меня есть конечный автомат, который должен вызывать разные методы для каждого объекта из списка объектов в зависимости от состояния, в котором я нахожусь. В основном я пытаюсь реорганизовать код, который имеет цикл в каждом операторе case мой конечный автомат, чтобы он выглядел как код ниже. Однако я не могу понять, как передать соответствующий метод в мою рефакторированную функцию (не говоря уже о том, что я не знаю, как вызывать его для каждого элемента)

Любая помощь будет оценена.

Вот пример кода:

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

Ответы [ 2 ]

2 голосов
/ 09 сентября 2011

Я бы предложил избавиться от таких switch блоков и отделить каждый конкретный метод от состояния, введя гибкую карту стратегии для каждого состояния, чтобы ее можно было легко изменить или даже ввести:

IDictionary<MyState, Func<bool>> strategyMap;

1) Заполните

 // 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) Вызов соответствующей стратегии зависит от состояния, а не switch(State)

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

Не стесняйтесь спрашивать в случае возникновения вопросов

0 голосов
/ 09 сентября 2011

Одно из возможных решений - сделать методы статичными и взять в качестве параметра ссылку на класс, с которым они должны работать:

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