C#使用LINQ重构gigantic switch语句以进行排序

时间:2015-06-17 09:59:10

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

我的问题是重复的代码:一个不那么DRY切换语句。

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

可排序的属性:

enter image description here

这是一个页面,如果用户点击一个头,表就会被命令:

enter image description here

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

enter image description here

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

4 个答案:

答案 0 :(得分:2)

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

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

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

答案 1 :(得分:1)

您可以在此方案中使用表达式树。

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) 

希望这有帮助。

答案 2 :(得分:0)

试试这个:

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

答案 3 :(得分:0)

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

然后你可以做到:

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