2016-12-01 51 views
0

我想確定最乾淨的(這是很好,如果它可以很容易地理解)的方式來確定哪些行動來執行給定的元組列表。
比方說,我有表MyType和表MyAction。這些表由一箇中間表ActionsPerType連接,因爲MyType與MyAction有多對多的關係。現在乾淨地確定給定一個枚舉元組的行爲

,這個想法是執行ActionsPerType宣佈的行動,例如:

Dictionary<int, int> actionsPerType = context.ActionsPerType 
    .GroupBy(c => c.MyTypeId) 
    .ToDictionary(c => c.Key.MyTypeId, c.ToList()); 

我想將此轉換爲Dictionary<int, Func<Task<decimal>>>,其中KeyactionsPerType.KeyValue在規定的async Task<decimal>列表代碼。

是否有任何這更簡潔的方法不是像(在這裏完成的,未經測試):

foreach (var item in actionsPerType) 
{ 
    switch ((MyTypeEnum)item.Key) 
    { 
     case MyTypeEnum.Random: 
     { 
      foreach (var action in actionsPerType[MyTypeEnum.Random]) 
      { 
       switch ((MyActionEnum)action) 
       { 
        case MyActionEnum.Random: 
         dictionary[MyTypeEnum.Random].Add(SomeTaskThatReturnsBool); 
         break; 
       } 
      } 
     } 
    } 
} 

MyTypeEnum將舉行約10項,而MyActionEnum將舉行近25,所以這將是很長的又醜。

+0

嘗試這種情況:字典> actionsPerType = context.ActionsPerType .GroupBy(C => c.MyTypeId,d => d) .ToDictionary(C => c.Key,d.ToList() );你可以用'd'作爲參數調用一個輔助方法 – jdweng

回答

1

就我個人而言,我是屬性的忠實粉絲。我並不完全確定所需的結果,如果以下情況適合您的情況,但這裏有所瞭解。

因爲enum被認爲是常量,所以它們可以在屬性參數中使用。因此,以下是可能的:

public enum TypeEnum{ 
    T1,T2 
} 

public enum ActionEnum{ 
    A1,A2 
} 

public static class SomeClass 
{ 
    [TypeAction(TypeEnum.T1, ActionEnum.A1)] 
    public static void Foo(){ 
    } 

    [TypeAction(TypeEnum.T1, ActionEnum.A2)] 
    [TypeAction(TypeEnum.T2, ActionEnum.A2)] //<-- example of method can be used for multiple types/actions 
    public static void Bar(){ 
    } 
} 

[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] // <- AllowMultiple in case an action can be used multiple times 
public class TypeActionAttribute:Attribute 
{ 
    public TypeActionAttribute(TypeEnum type, ActionEnum action) 
    { 
     this.Type=type; 
     this.Action = action;   
    } 

    public TypeEnum Type{get;set;} 
    public ActionEnum Action{get;set;} 
} 

一旦創建屬性類,每個枚舉組合可以分配給任何方法。獲得所有方法可以在運行時完成(最好在初始化和記憶期間執行一次)。 大概可能的組合列表是從長遠來看,最有用的,但是你的例子似乎只需要TypeEnum所有方法(ActionEnum不存儲在pseudecode),這將在類似相當於:

var typeMethods = (from m in typeof(SomeClass).GetMethods() //the methods are probably based in multiple types. Depending where they can be found, the types of an Assembly can be queried 
      from a in m.GetCustomAttributes(typeof(TypeActionAttribute), true)    
      group m by ((TypeActionAttribute)a).Type) 
      .ToDictionary(gr=>gr.Key, gr=>gr.ToList()); 

typemethods將是一個帶有methodinfo列表的TypeEnum字典。 (該方法可以調用或處理到特定的lambda)

+0

我接受了你的答案,因爲我喜歡它,但我們決定使用中間表 –

0

我真的很喜歡@Me.Name給出的答案。但是,如果由於某種奇怪的原因屬性是不是一種選擇,爲什麼不使用任務的字典:

Dictionary<MyActionEnum, Func<Task<decimal>>> tasks = new Dictionary<MyActionEnum, Func<Task<decimal>>> { 
       { MyActionEnum.A1, __Task1 }, 
       { MyActionEnum.A2, __Task2 }, 
       { MyActionEnum.A3, __Task3 }, 
       { MyActionEnum.A4, __Task4 }, 
       { MyActionEnum.A5, async() => { return await Task.Delay(5000).ContinueWith(result => new Decimal(16)); } } 
      }; 
static async Task<decimal> __Task1() { return await Task.FromResult<decimal>(new Decimal(420)); } 
// etc 

如果我理解你的要求,那麼這應該與LINQ完全滿足需要,我想這裏的優點是字典允許用於運行時動態。