Убираем if и switch в C#: элегантный и масштабируемый код

В статье рассматриваются два подхода к уменьшению использования условной логики (if и switch) в C#, способствующие повышению элегантности и масштабируемости кода. Полное исключение if и switch не всегда целесообразно, однако знание альтернативных методов является ценным навыком.

Обработка множества однотипных случаев

Рассмотрим метод ShowInfo, выводящий информацию о различных предметах. Простая реализация с switch приводит к дублированию кода, изменяются только литералы. Добавление нового предмета требует модификации каждого случая, что неудобно и подвержено ошибкам. Аналогично, изменение формата вывода требует корректировки каждого обработчика.

Для устранения switch, применим факторинг (извлечение метода). Создадим отдельный метод ShowItemInfo, принимающий параметры (описание и цвет предмета) и выводящий информацию. Метод ShowInfo будет вызывать ShowItemInfo с соответствующими параметрами.

// Первоначальный код с switch
public void ShowInfo(string item)
{
    switch (item)
    {
        case "предмет1":
            // Вывод информации о предмете1
            break;
        case "предмет2":
            // Вывод информации о предмете2
            break;
        // ... и так далее
    }
}

// Код после рефакторинга
public void ShowInfo(string item)
{
    // ... определение параметров для ShowItemInfo на основе item ...
    ShowItemInfo(description, color);
}

private void ShowItemInfo(string description, string color)
{
    // Вывод информации с использованием description и color
}

Для хранения информации о предметах используем массив объектов. Создадим класс Item с полями Description и Color. Объекты Item хранятся в массиве, индексируются и используются в ShowItemInfo.

public class Item
{
    public string Description { get; set; }
    public string Color { get; set; }
}

// ... далее код с использованием массива Item ...

В результате, switch убран. Добавление новых предметов сводится к добавлению элементов в массив, а изменение формата вывода – к изменению метода ShowItemInfo.

Изменение алгоритма в зависимости от типа

Рассмотрим сущность Enemy с различными типами (человек, животное, здание). Алгоритм нанесения урона зависит от типа. Реализация с switch приводит к дублированию кода.

Применим полиморфизм. Создадим абстрактный класс Enemy с абстрактным методом DealDamage. Создадим производные классы (Human, Animal, Building), переопределяющие DealDamage для каждого типа.

public abstract class Enemy
{
    public int Health { get; set; }
    public abstract void DealDamage(int damage);
}

public class Human : Enemy
{
    public override void DealDamage(int damage) { Health -= damage; }
}

public class Animal : Enemy
{
    public override void DealDamage(int damage) { Health -= damage * 2; }
}

public class Building : Enemy
{
    public override void DealDamage(int damage) { Health -= 10; }
}

Теперь, вместо switch, вызываем DealDamage напрямую. Полиморфизм обеспечивает вызов правильной реализации в зависимости от типа объекта.

// Пример использования
Enemy enemy = new Human();
enemy.DealDamage(10); // Вызов метода Human.DealDamage

В статье представлены два метода уменьшения избыточной условной логики. Выбор метода зависит от ситуации. Факторинг и полиморфизм делают код чище, понятнее и проще в поддержке. Избавление от if и switch не является самоцелью, а средством улучшения качества кода.

Что будем искать? Например,программа