Как я могу реорганизовать этот оператор switch? - PullRequest
1 голос
/ 05 февраля 2009

Вчера я играл с плагином jQGrid и ASP.NET. Все оказалось хорошо, моя сетка работает сейчас, но у меня есть два метода, которые заставляют мой код пахнуть.

Вонючие методы:

private IOrderedEnumerable<Employee> GetOrderedEmployees(Column sortColumn, bool ascending)
    {
        switch (sortColumn)
        {
            case Column.Name:
                {
                    return GetOrderedEmployees(e => e.Name, ascending);
                }
            case Column.Salary:
                {
                    return GetOrderedEmployees(e => e.Salary, ascending);
                }
            default:
                {
                    return GetOrderedEmployees(e => e.ID, ascending);
                }
        }
    }

    private IOrderedEnumerable<Employee> GetOrderedEmployees<TSortKey>(Func<Employee, TSortKey> func, bool ascending)
    {
        return ascending ? Context.Employees.OrderBy(func) : Context.Employees.OrderByDescending(func);
    }

Я не могу понять, как правильно их реорганизовать. Кажется, лучшее решение - вернуть только лямбда-выражения (например, return e=>e.Name) в операторе switch, но как это сделать?

В операторе switch ascending аргумент передается 3 раза. Разве это не дублирование?

Ответы [ 3 ]

7 голосов
/ 05 февраля 2009

Я думаю, что вы, возможно, идете сюда. Возвращение лямбда-выражения (IMO) гораздо более запутанно, чем простой оператор switch или блок if, else if, else. Возможно, есть и лучший способ, но иногда вам нужно проверить условие, особенно со столбцами (я НЕНАВИЖУ работать с ListViews, но они необходимы и часто требуют такого рода кода).

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

Чтобы решить проблему дублирования кода, вы можете использовать переключатель, чтобы получить е. ?? сначала значение, сохраните его, а затем вызовите функцию один раз в конце метода.

2 голосов
/ 05 февраля 2009

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

Редактировать - Но я также считаю, что комментарий первого автора имеет много достоинств - в любом случае не принимайте комплексное решение для чего-то, что является маленьким картофелем.

0 голосов
/ 05 февраля 2009

Если вы просто пытаетесь уменьшить дублирование в вашем коде:

private IOrderedEnumerable<Employee> GetOrderedEmployees(Column sortColumn, bool ascending)
{
    Func<Employee, TSortKey> func = e => e.ID;

    switch (sortColumn)
    {
        case Column.Name:
            {
                func = e => e.Name;
            }
        case Column.Salary:
            {
                func = e => e.Salary;
            }
    }

    return GetOrderedEmployees(func, ascending);
}

private IOrderedEnumerable<Employee> GetOrderedEmployees<TSortKey>(Func<Employee, TSortKey> func, bool ascending)
{
    return ascending ? Context.Employees.OrderBy(func) : Context.Employees.OrderByDescending(func);
}

(Я не владею .NET; прошу прощения за любые синтаксические ошибки.)

...