Вы можете добавить делегата в класс 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);
}
}
Хитрость заключается в использовании делегата Action<MyObjects>
, принимающего MyObjects
в качестве параметра.Это позволяет вам указать лямбда-выражение, которое вызывает метод для этого объекта.Вы даже можете передать параметры таким методам, если требуется:
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
, он будет вызывать Console.WriteLine
напрямую.(Обратите внимание, я предполагаю, что вы переопределили ToString
в MyObjects
, в противном случае будет напечатано только имя типа.)
См. Также: Лямбда-выражения (Руководство по программированию в C #) *