缩短简单的c#代码

时间:2014-08-06 04:37:47

标签: c# optimization switch-statement

我有这个代码可以完美运行,但它对我来说并不好看。我想尽可能缩短这段代码。 提升是一个布尔和& 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;
    }

4 个答案:

答案 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)

答案 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