c# - 以不同的顺序对集合中的对象执行几种方法
问题描述
我的应用程序中的用户可以决定为对象集合执行哪些活动以及以什么顺序执行。顺序在所有对象的开头(一次)设置。
用户选择的方法应由应用程序以正确的顺序执行。
例如,我定义了动作列表:
this.ActionsList = new List<MyAction>
{
new MyAction {Id = "123", Order = 1, Text = "Method 5", IsActive = true},
new MyAction {Id = "abc", Order = 5, Text = "Method 1", IsActive = false},
new MyAction {Id = "def", Order = 3, Text = "Method 3", IsActive = true}
};
我还有一个对象集合:
var myObjects = new List<MyObjects>();
现在,对于集合中的每个对象,程序必须调用与激活的操作相关的方法。定义的操作定义将调用哪个方法。
foreach (var o in myObjects){
var actions = ActionsList.Where(x => x.IsActive).OrderBy(x => x.Order);
foreach (var a in ActionsList){
switch(a.Id){
case "123":
o.Method5();
break;
case "abc":
o.Method1();
break;
// etc...
}
}
}
请忽略任何不准确之处。
此解决方案有效。但是,“切换”指令非常大。我有几十个这样的动作。这可能不是最好的解决方案。
我认为最好的解决方案是为每个对象“MyAction”指明适当的方法(委托):
new MyAction {Id = "def", Order = 3, Text = "Method 3", IsActive = true,
MethodToCallDelegate = Method3}
我不知道如何实现它(或类似的解决方案)。我希望我的代码在以后的版本中是透明和简单的。
解决方案
MyAction
您可以向班级添加委托
public Action<MyObjects> Action { get; set; }
然后可以像这样初始化操作列表:
this.ActionsList = new List<MyAction> {
new MyAction { Order = 1, Text = "Method 5", Action = o => o.Method5(), IsActive = true },
new MyAction { Order = 5, Text = "Method 1", Action = o => o.Method1(), IsActive = false },
new MyAction { Order = 3, Text = "Method 3", Action = o => o.Method3(), IsActive = true }
};
可以像这样应用这些动作
var orderedActions = ActionsList
.Where(a => a.IsActive)
.OrderBy(a => a.Order)
.ToList();
foreach (MyObjects o in myObjects) {
foreach (MyAction action in orderedActions) {
action.Action(o);
}
}
诀窍是使用接受 a作为参数的Action<MyObjects>
委托。MyObjects
这允许您指定调用此对象上的方法的 lambda 表达式。如果需要,您甚至可以将参数传递给此类方法:
Action = o => o.StringMethod1("Hello")
Action = o => o.StringMethod2("Hello", "World")
或者做完全不同的事情
Action = o => o.Text = "okay"
Action = o => Console.WriteLine(o)
Action = o => { o.Text = "statement lambda"; Console.WriteLine(o); }
委托保持不变,因为它始终只有一个MyObjects
参数。
在您想要调用与Action<MyObjects>
委托兼容的方法的特殊情况下,您可以将方法本身作为委托传递。您省略参数大括号以表明您不想在此处调用它。
Action = Console.WriteLine
这将具有相同的效果,o => Console.WriteLine(o)
但效率更高。Console.WriteLine
它不会调用从依次调用的 lambda 表达式创建的委托,而是Console.WriteLine
直接调用。(注意,我假设您已覆盖ToString
in MyObjects
,否则只会打印类型名称。)
另请参阅:Lambda 表达式(C# 编程指南)
推荐阅读
- uwp - Uno 平台 - 如何使用来自不同项目的用户控件?
- xslt - xsl 命名空间从根复制到子节点,copy-namespaces="no" 不起作用(xslt 3.0 版本)
- spring - 使用 Spring、MongoDB 和 Kotlin 进行 JUnit 依赖注入
- python - 我不能按列名提取数据?
- javascript - 使用拼接删除 JSON 对象无处可去 - 那么我如何删除一大块数据?
- rpa - UiPath 中列中的值 - 需要最有效的方法
- reactjs - React Native 与其他(父)组件共享滚动动画事件
- mysql - 如何执行左连接,以便从左表中获取每条记录,而不管右表上的条件如何
- office-ui-fabric - 如何在fluentui(office ui fabric)中创建一个“危险”按钮?
- sql - 订单中的所有捆绑产品(订单项目列表)