Вернуть значение из метода, если не выполняются условия C#

221
06 января 2019, 12:10

Как правильно поступить в ситуации, в методе находится ряд условий, если они удовлетворяются, то возвращается значение из словаря. Как поступить, если ни одно из условий не проходит условие? Класс - модель данных:

public class SecondModel
{
    public Dictionary<int, double> FirstDepartment { get; set; }
    public Dictionary<int, double> SecondDepartment { get; set; }
    public Dictionary<int, double> ThirdtDepartment { get; set; }
}

Провайдер

public class SecondManager
{
    private SecondModel _model;
    public enum Department
    {
        First,
        Second,
        Third
    };
    /// <summary>
    /// Конструктор по умолчанию
    /// </summary>
    public SecondManager()
    {
        _model = new SecondModel()
        {
            FirstDepartment = new Dictionary<int, double>(),
            SecondDepartment = new Dictionary<int, double>(),
            ThirdtDepartment = new Dictionary<int, double>()
        };
        _model.FirstDepartment.Add(1, 30.2);
        _model.FirstDepartment.Add(2, 25.8);
        _model.SecondDepartment.Add(3, 45.67);
        _model.SecondDepartment.Add(4, 54.46);
    }
    double GetValuesByKey(Department department, int key)
    {
        if (department == Department.First && _model.FirstDepartment.ContainsKey(key))
            return _model.FirstDepartment[key];
        if (department == Department.Second && _model.SecondDepartment.ContainsKey(key))
            return _model.FirstDepartment[key];
        if (department == Department.Third && _model.ThirdtDepartment.ContainsKey(key))
            return _model.ThirdtDepartment[key];
        // Еcли ключа или направления не существует
        return ???;
    }
}

Может вернуть infinity?

Answer 1

Не люблю я нагороженные if-ы в подобных методах, я бы такой код написал и задокументировал т.к. поведение метода не совсем очевидно

/// <summary>
/// Возвращает значение по данному ключу в направлении если существует, в противном случае - возвращает null
/// </summary>
/// <param name="department">Направление</param>
/// <param name="key">Ключ</param>
/// <returns>Значение по данному ключу в направлении</returns>
double? GetValueByKey(Department department, int key)
{
    switch (department)
    {
        case Department.First when _model.FirstDepartment.ContainsKey(key):
            return _model.FirstDepartment[key];
        case Department.Second when _model.SecondDepartment.ContainsKey(key):
            return _model.SecondDepartment[key];
        case Department.Third when _model.ThirdtDepartment.ContainsKey(key):
            return _model.ThirdtDepartment[key];
        default:
            return null;
    }
}
Answer 2

Если отвечать на вопрос прямо, то в случае, если не один их всех возможных вариантов не выполнен, то нужно бросать исключение. На самом деле такая ситуация невозможна лишь на момент написания программы, но если позднее кто-то расширит enum, то тут уже и станет реальным нарваться на вариант, который не возможно полноценно предусмотреть на момент написания. Однако, возвращение всяких вспомогательных значений, типа null, double.Infinity или -1 это нарушение семантики вашего метода --- GetValuesByKey(Department department, int key) не должен возвращать подобные значения-секреты. Поэтому в такой ситуации меняйте

return ???

на

throw new InvalidOperationException(
        $"Данным приложением не предусмотрена работа с отделом {department}")

Но, в этом конкретном случае, мы стали заложником антипаттерна Enum-Switch (Подробнее статья (хоть и спорная) на Хабрахабр). Нельзя с помощью Enum реализовать список значений, который по своей природе склонен к изменению.

Например, в царстве Растения 12 отделов. И это вряд ли измениться за время жизни приложения. А в компании N сегодня 3 отдела, а завтра расширение, сокращение или кадровая реформа, и как результат, совершенно другой состав и количество этих отделов.

READ ALSO
Как сделать пагинацию в Entity Framework Core и API

Как сделать пагинацию в Entity Framework Core и API

Есть поисковой запрос,который выводит значения из базы данныхПроблема в том,что вхождений может быть огромное количество и поэтому хочу...

207
Значение из текста

Значение из текста

Как можно средствами C# получить определенную часть строки?

165
запрет клик мышкой по ListBox C# (windows form)

запрет клик мышкой по ListBox C# (windows form)

У меня есть кнопки который переключают Items, но у меня не получается запретить клик мышкой по ListBox, обшарил гугл, не нашёл(Либо я слепой)Помогите...

186
LiqPay обрывает сессию. ASP.NET Core

LiqPay обрывает сессию. ASP.NET Core

Проблема вот в чемЯ делаю успешно оплату по этому сервису у себя на сайте где после оплаты автоматический редирект на метод в котором в таблице...

165