Lambda 如何重构这个switch语句?

Lambda 如何重构这个switch语句?,lambda,switch-statement,Lambda,Switch Statement,昨天我在玩jQGrid插件和ASP.NET。一切都很好,我的网格现在正在运行,但我有两种方法,使我的代码有味道 臭方法: private IOrderedEnumerable<Employee> GetOrderedEmployees(Column sortColumn, bool ascending) { switch (sortColumn) { case Column.Name: {

昨天我在玩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语句中只返回lambdas f.e return e=>e.Name,但是如何实现呢


在switch语句中,升序参数传递了3次。这不是重复吗?

我想你在这里可能有点过头了。返回lambdas IMO比简单的switch语句或if更容易混淆;否则,如果;否则就要封锁。也许有更好的方法,但有时确实需要检查一个条件,特别是对于我讨厌使用ListView的列,但它们是必需的,并且通常需要这种代码

我不认为您现在需要重构任何东西。如果那个switch语句成为维护上的一个难题,那就继续吧,但并不是所有switch语句都构成了代码气味


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

我认为您可能在这里做得太过分了。返回lambdas IMO比简单的switch语句或if更容易混淆;否则,如果;否则就要封锁。也许有更好的方法,但有时确实需要检查一个条件,特别是对于我讨厌使用ListView的列,但它们是必需的,并且通常需要这种代码

我不认为您现在需要重构任何东西。如果那个switch语句成为维护上的一个难题,那就继续吧,但并不是所有switch语句都构成了代码气味


为了解决代码重复问题,您可以使用开关获取e。??首先,保存该值,然后在方法末尾调用该函数一次。

这里可能有一些模式可以使用,但是提供程序如何?您可以创建一个提供GetOrderEmployees的提供程序,然后传入要使用的提供程序,而不是排序列

编辑-
但我也认为第一张海报的评论有很多优点——不管怎样,不要为一些微不足道的事情制定复杂的解决方案。

这里有一些模式可能奏效,但是提供商呢?您可以创建一个提供GetOrderEmployees的提供程序,然后传入要使用的提供程序,而不是排序列

编辑-
但我也认为第一张海报的评论有很多优点——不管怎样,不要为微不足道的事情制定复杂的解决方案。

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

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不是很流利;请原谅任何语法错误。

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

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不是很流利;请原谅任何语法错误。

请提出一个其他人在搜索时可以理解的问题:请提出一个其他人在搜索时可以理解的问题:在我的方法中,我必须通过升序参数3次。这让我困惑,因为这是一种重复?在我的方法中,我必须通过3次升序论证。这让我很困惑,因为它有点重复?这里的关键问题是我不能为每个列泛化Func-ID有int类型、Name-string类型和Salary-decimal类型。可能我在参数中犯了一个非常愚蠢的错误,但我在.net3+中没有。这里的关键问题是我不能为每个列泛化Func-ID有int类型、Name-string类型和Salary-decimal类型。也许我在辩论中犯了一个非常愚蠢的错误,但我在.net3+中没有任何错误。