2016-12-01 8 views
0

与えられたタプルのリストを実行するアクションを決定する最もクリーンな方法(簡単に理解できれば十分です)を判断しようとしています。
テーブルMyTypeとテーブルMyActionがあるとします。 MyTypeはMyActionと多対多の関係を持っているため、これらの表は中間表のActionsPerTypeで結合されます。enumタプルで与えられたアクションをきちんと決める

さて、アイデアは例えば、ActionsPerTypeが宣言したアクションを実行することです:

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

私はKeyactionsPerType.Keyで、Valueがで定義されたasync Task<decimal>のリストであるDictionary<int, Func<Task<decimal>>>にこれを変換したいですコード。 MyActionEnumは25近く開催する一方で

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項目を開催するので、これは本当に長いと醜い次のようになります。

は(ここで行わ、テストされていない)のようなものよりも、これに任意のクリーンなアプローチがあります。

+0

これを試してみてください:辞書> actionsPerType = context.ActionsPerType .GroupBy(C => c.MyTypeId、D => D) .ToDictionary(C => c.Key、d.ToList() );パラメータとして 'd'を使用してヘルパーメソッドを呼び出すことができます – jdweng

答えて

1

個人的に私は属性の大きなファンです。私は望みの結果が完全にはわかりませんし、あなたの状況に合っているならばここに行きます。

は定数と見なされるため、属性パラメータ内で使用できます。したがって、次のことが可能です:

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

属性クラスが作成されると、各列挙型コンビはどのメソッドにも割り当てることができます。すべてのメソッドの取得は、実行時に行うことができます(初期化中に1回、メモを取ることが望ましい)。 はおそらく可能な組み合わせのリストは、長期的に最も有用ですが、あなたの例のようなものに相当すると思われる、すべてのメソッド(ActionEnumはpseudecodeに格納されていない)でのみTypeEnumを必要としているようだ:

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の辞書になります。 (このメソッドは特定のラムダに呼び出すか処理することができます)

+0

私はそれが好きなのであなたの答えを受け入れましたが、私たちは中間テーブルを使ってこれを行うことにしました –

0

私は本当に@ Me.Nameの答えが好きです。しかし、いくつかの奇妙な理由で属性がタスクの辞書は使用しない理由を選択しない場合:私はあなたの要件を理解していれば、これはLINQできちんと合うべきです、と私はここでの利点は、辞書が可能であることであると仮定し

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 

をランタイムダイナミクスのために。

関連する問題