【问题标题】:C# Refactoring gigantic switch statement for ordering with LINQC# 重构巨大的 switch 语句以使用 LINQ 进行排序
【发布时间】:2015-06-17 09:59:09
【问题描述】:

我的问题是重复代码:一个不太干的 switch 语句。

所以我有一个包含 12 列的表格,点击时可以按降序或升序排序。我目前的解决方案是使用 switch 语句来检查点击了哪一列。

可排序的属性:

如果用户点击头部,则在该页面中对表格进行排序:

SortByColumn 属性以字符串形式出现。 SortAscending 布尔值来自 @Html.CheckBoxFor

你知道这是怎么回事吗?我有 12 列可以订购,所以这个开关会变得非常冗长且无法维护。所以我的问题是,是否可以通过反射或其他方式重构它?

【问题讨论】:

标签: c# asp.net-mvc linq dry


【解决方案1】:

OrderBy 函数的工作原理是让您返回它应该排序的属性,它将被称为列表中的每个项目。

我们可以使用反射代替硬编码:

public ActionResult Index(AgentReportViewModel vm)
{
    var b = Agent.GetAgents();
    vm.Agents = vm.SortAscending 
        ? b.OrderBy(x => GetValueByColumn(x, vm.SortByColumn))
        : b.OrderByDescending(x => GetValueByColumn(x, vm.SortByColumn));
    return View(vm);
}

public object GetValueByColumn<T>(T x, string columnStr)
{
    // Consider caching the property info, as this is a heavy call.
    var propertyInfo = x.GetType().GetProperty(columnStr);    
    return propertyInfo.GetValue(x, null);
}

【讨论】:

    【解决方案2】:

    您可以在这种情况下使用表达式树。

    public static Func<Agent, object> GetOrderBySelector(string propertyName)
    {
        var parameter = Expression.Parameter(typeof(Agent), "a");
        var property = Expression.Property(parameter, propertyName);
        // a => a.PropertyName is a unary expression
        var unaryExpression = Expression.Convert(property, typeof(object));
        // Create the lambda for the unary expression with the given property 
        // information and compile to return the actual delegate.
        return Expression.Lambda<Func<Agent, object>>(unaryExpression, parameter).Compile();
    }
    

    用法:

    b.OrderBy(vm.SortByColumn) 
    

    b.OrderByDescending(vm.SortByColumn) 
    

    希望这会有所帮助。

    【讨论】:

      【解决方案3】:

      试试这个:

      var SortByColumnStr = "Answer"; //Dynamic string
      var propertyInfo = typeof(Agent).GetProperty(SortByColumnStr);    
      List<Agent> b.OrderBy(x => propertyInfo.GetValue(x, null));
      

      参考:https://stackoverflow.com/a/7265394/1660178

      【讨论】:

        【解决方案4】:

        看看 System.Linq.Dynamic(NuGet 包可用)。

        那么你可以这样做:

        string sortingString = string.Format("{0} {1}",vm.OrderByColumn, vm.SortAscending ? "ASC" : "DESC");
        vm.Agents = Agent.GetAgents().OrderBy(sortingString).ToList();
        

        【讨论】:

          猜你喜欢
          • 2012-10-07
          • 2023-03-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-11-28
          • 2016-06-05
          相关资源
          最近更新 更多