2011-09-09 18 views
2

我有一個狀態機,需要根據我所處的狀態從對象列表中調用每個對象上的不同方法。基本上我試圖重構在每個case語句中有一個循環的代碼狀態機,使其看起來像下面的代碼。但我似乎無法弄清楚如何將相關方法傳遞給我的重構函數(更不用說我不知道​​如何在每個項目上調用它)在C#中,如何使用Func <T>從另一個類傳遞一個方法?

任何幫助,將不勝感激。

這裏的示例代碼:

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

在我看來,這更多的是設計問題而不是'Func '的問題。 – thekip

回答

2

我建議擺脫這種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

絕妙的主意,儘管在我的真實代碼中,我可能會在給定狀態下進行其他處理。不過,這個答案將使我能夠根據需要進行重構,所以謝謝! – Akuma

+0

@Akuma:太棒了,歡迎您! – sll

0

一個可行的辦法是使方法靜態和走班基準應當在經營情況作爲參數:

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

是的,我曾考慮過這個問題,但由於我試圖重構一個只通過方法調用改變的重複循環,因此爲此目的生成大量額外的靜態方法似乎是反效果的。但它仍然是一個有效的建議,謝謝。 – Akuma

相關問題