我正在尝试确定最干净的(如果可以很容易理解的话,那就足够了)确定在给定元组列表时要执行哪些操作的方法。
让我们说我有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>>>
,其中Key
是actionsPerType.Key
,Value
是代码中定义的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 :(得分: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
将是TypeEnum的字典,其中包含methodinfo&s的列表。 (methodinfos可以被调用或处理为特定的lambdas)
答案 1 :(得分: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完全吻合,我想这里的优点是字典允许运行时动态。