如何重构这个 switch 语句?

发布于 2024-07-13 22:51:35 字数 1111 浏览 4 评论 0原文

昨天我在玩 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);
    }

我不知道如何正确重构它们。 看起来最好的解决方案是在 switch 语句中仅返回 lambda (fe return e=>e.Name),但如何才能做到呢?

在 switch 语句中,ascending 参数被传递 3 次。 不是重复吗?

Yesterday I was playing with jQGrid plugin and ASP.NET. Everything turned out well, my grid is working now, but I have two methods, that make my code smell.

Smelly methods:

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);
    }

I can't find out, how to refactor them properly. It's seems the best solution is to return only lambdas (f.e return e=>e.Name) in the switch statement, but how can it be done?

In the switch statement ascending argument is passed 3 times. Isn't it a duplication?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

醉南桥 2024-07-20 22:51:35

我认为你可能有点过分了。 返回 lambda (IMO) 比简单的 switch 语句或 if;else if;else 块更令人困惑。 可能有更好的方法,但有时您确实需要检查条件,特别是对于列(我讨厌使用 ListViews,但它们是必要的并且通常需要这种代码。)

我不认为您处于您需要重构任何内容的点。 如果该 switch 语句成为维护难题,那么就继续吧,但并非所有 switch 语句都构成“代码异味”。

为了解决您的代码重复问题,您可以使用开关来获取 e.?? 首先将值保存下来,然后在方法结束时调用该函数一次。

I think that you may be going over the top here. Returning lambdas (IMO) is far more confusing than a simple switch statement or if;else if;else block. There may be a better way, but sometimes you do need to check a condition, especially with columns (I HATE working with ListViews, but they are necessary and often require this kind of code.)

I don't think that you are at the point in which you need to refactor anything. If that switch statement becomes a maintenance headache, than go right ahead, but not all switch statements constitute "code smell".

To address your code duplication concern, you can use the switch to get the e.?? value first, save that off and then call the function once at the end of the method.

疑心病 2024-07-20 22:51:35

有一些模式可能在这里起作用,但是提供者怎么样? 您可以创建一个提供 GetOrderEmployees 的 Provider,然后传入您想要使用的 Provider 而不是排序列。

编辑 -
但我也认为第一个发帖者的评论有很多优点——无论如何,不​​要为小事制定复杂的解决方案。

There are a few patterns that might work here, but how about a Provider? You could create a Provider that provides a GetOrderEmployees, then pass in the Provider you want used instead of the sort column.

Edit -
But I also thing the first poster's comment has a lot of merit - don't make a complex solution for something that's small potatoes anyway.

独守阴晴ぅ圆缺 2024-07-20 22:51:35

如果您只是想减少代码中的重复:(

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;请原谅任何语法错误。)

If you're just trying to reduce the duplication in your code:

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);
}

(I'm not fluent in .NET; please forgive any syntax errors.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文