Как создать конструкцию 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 шт):

Автор решения: aepot

Допустим, у вас есть некий класс с методами, которые надо вызывать, как я понял, асинхронными.

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];
→ Ссылка