我有这个代码可以完美运行,但它对我来说并不好看。我想尽可能缩短这段代码。 提升是一个布尔和& sort是字符串。
if(ascending)
switch (sort)
{
case "ID":
return lstFiltered.OrderBy(o => o.ID).ToList();
case "Device_Name":
return lstFiltered.OrderBy(o => o.Device_Name).ToList();
case "ErrorType_Name":
return lstFiltered.OrderBy(o => o.ErrorType_Name).ToList();
case "Error_Name":
return lstFiltered.OrderBy(o => o.Error_Name).ToList();
case "WAIT_TIME":
return lstFiltered.OrderBy(o => o.WAIT_TIME).ToList();
default:
return lstFiltered;
}
else
switch (sort)
{
case "ID":
return lstFiltered.OrderByDescending(o => o.ID).ToList();
case "Device_Name":
return lstFiltered.OrderByDescending(o => o.Device_Name).ToList();
case "ErrorType_Name":
return lstFiltered.OrderByDescending(o => o.ErrorType_Name).ToList();
case "Error_Name":
return lstFiltered.OrderByDescending(o => o.Error_Name).ToList();
case "WAIT_TIME":
return lstFiltered.OrderByDescending(o => o.WAIT_TIME).ToList();
default:
return lstFiltered;
}
答案 0 :(得分:2)
使用Reverse摆脱第二个开关:
// define sorted as IEnumerable<T> where T is the actual generic type of lstFiltered
switch (sort)
{
case "ID":
sorted = lstFiltered.OrderBy(o => o.ID);
break;
case "Device_Name":
sorted = lstFiltered.OrderBy(o => o.Device_Name);
break;
case "ErrorType_Name":
sorted = lstFiltered.OrderBy(o => o.ErrorType_Name);
break;
case "Error_Name":
sorted = lstFiltered.OrderBy(o => o.Error_Name);
break;
case "WAIT_TIME":
sorted = lstFiltered.OrderBy(o => o.WAIT_TIME);
break;
default:
sorted = lstFiltered;
}
if (!ascending) // do reverse ordering
sorted = sorted.Reverse();
return sorted.ToList();
答案 1 :(得分:1)
esskar的解决方案,在这里有一点反思..
var sorted = lstFiltered.OrderBy(
o => o.GetType()
.GetProperty( sort )
.GetValue( o, null ));
if (!ascending)
sorted = sorted.Reverse();
return sorted.ToList();
答案 2 :(得分:0)
查看ScottGu的旧文章 - 动态查询库 http://weblogs.asp.net/scottgu/dynamic-linq-part-1-using-the-linq-dynamic-query-library
此处的现有扩展也很少 How do I specify the Linq OrderBy argument dynamically?
答案 3 :(得分:0)
实现这一目标的有趣方法是通过Reflection。其他答案使用Reflection获取属性,然后为每个元素获取一次值,这相当慢。
更好的方法是只获取属性一次,然后为每个元素调用一次getter:
IEnumerable<T> sorted = lstFiltered;
var property = typeof(T).GetProperty(sort);
if (property != null)
if (ascending)
sorted = sorted.OrderBy(o => property.GetValue(o, null));
else
sorted = sorted.OrderByDescending(o => property.GetValue(o, null));
return sorted.ToList();
请注意,这会检测到使用不存在的属性,并且(就像原始代码一样)在这种情况下不会对列表进行排序。
更好(更快),是使用Reflection创建一个可以传递给OrderBy
的委托:
IEnumerable<T> sorted = lstFiltered;
var property = typeof(T).GetProperty(sort);
if (property != null)
{
var getter = (Func<T, object>)Delegate
.CreateDelegate(typeof(Func<T, object>),
property.GetGetMethod());
if (ascending)
sorted = sorted.OrderBy(getter);
else
sorted = sorted.OrderByDescending(getter);
}
return sorted.ToList();
但这仅适用于参考类型。如果您将要使用值类型,最简单的方法可能是为OrderBy
创建一个表达式并进行编译。这将花费一点时间进行编译,但会尽快执行:https://stackoverflow.com/a/7265354/310574