Как создать конструкцию switch при помощи циклов
Условно в базе есть таблица: Net 6.0
| Id | Name | ShortName |
|---|---|---|
| 1 | Меню 1 | Menu1 |
| 2 | Меню 2 | Menu2 |
| 3 | Меню 3 | Menu3 |
Как заполнить подобное выражение данными из таблицы при помощи цикла?
var action = test switch {
"Меню 1" => Menu1(),
"Меню 2" => Menu2(),
"Меню 3" => Menu3(),
_ => Default()
};
Ответы (1 шт):
Допустим, у вас есть некий класс с методами, которые надо вызывать, как я понял, асинхронными.
public class MenuActions
{
public async Task Menu1()
{
await Task.Delay(100);
PrintCallerName();
}
public async Task Menu2()
{
await Task.Delay(100);
PrintCallerName();
}
public async Task Menu3()
{
await Task.Delay(100);
PrintCallerName();
}
private void PrintCallerName([CallerMemberName] string name = null)
{
Console.WriteLine($"{name} was called");
}
}
Тогда вы можете собрать эти методы в словарик в виде делегатов с помощью рефлексии. Пусть у нужных методов будет в названиях префикс Menu, чтобы не цеплять всякие наследуемые методы типа GetType().
MenuActions actions = new MenuActions();
Dictionary<string, Func<Task>> methods = typeof(MenuActions)
.GetMethods(BindingFlags.Public | BindingFlags.Instance)
.Where(m => m.Name.StartsWith("Menu"))
.ToDictionary(m => m.Name, m => m.CreateDelegate<Func<Task>>(actions));
Словарик готов.
Допустим, это будет строка таблицы в БД
public class MenuDBItem
{
public int Id { get; set; }
public string Name { get; set; }
public string ActionName { get; set; }
}
Допустим из базы пришли данные
MenuDBItem[] items = new MenuDBItem[]
{
new MenuDBItem { Id = 1, Name = "Меню 1", ActionName = "Menu1" },
new MenuDBItem { Id = 2, Name = "Меню 2", ActionName = "Menu2" },
new MenuDBItem { Id = 3, Name = "Меню 3", ActionName = "Menu3" },
};
Тогда вы можете с помощью словарика вызвать нужный метод по имени из базы
string methodName = items[1].ActionName;
if (methods.TryGetValue(methodName, out Func<Task> func))
await func();
else
Console.WriteLine($"{methodName} not found");
Вывод в консоль
Menu2 was called
Словарик можно и вручную собрать, а не с помощью рефлексии, только придется не забывать в него добавлять новые методы. Имейте в виду, что рефлексия - штука медленная. Не пересобирайте словарик каждый раз, это достаточно сделать один раз после создания класса с методами.
Что касается вашего switch, то он не нужен. Если нужно в экземпляр класса менюшки положить сразу делегат, то просто достаньте его из словарика.
menuItem.Action = methods[item.ActionName];