【问题标题】:Can it be done more cleaner and shorter?它可以做得更干净更短吗?
【发布时间】:2019-01-16 23:53:51
【问题描述】:

我有一个我认为不好的代码,因为它在每个 case 语句中都重复了类似的语句:

if (command.OrderProperty.ToLower().Equals("asc"))
{
   accessForms.Forms = accessForms.Forms.OrderBy(o => o.NumberForSort).ToList();
}
else
{
   accessForms.Forms = accessForms.Forms.OrderByDescending(o => o.NumberForSort).ToList();
}

唯一不同的是查询所依据的属性

switch (command.SortProperty.ToLower())
{
   case "number":
      if (command.OrderProperty.ToLower().Equals("asc"))
      {
         accessForms.Forms = accessForms.Forms.OrderBy(o => o.NumberForSort).ToList();
      }
      else
      {
         accessForms.Forms = accessForms.Forms.OrderByDescending(o => o.NumberForSort).ToList();
      }
      break;
   case "type":
      if (command.OrderProperty.ToLower().Equals("asc"))
      {
         accessForms.Forms = accessForms.Forms.OrderBy(o => o.Type).ToList();
      }
      else
      {
         accessForms.Forms = accessForms.Forms.OrderByDescending(o => o.Type).ToList();
      }
      break;
   case "employeename":
      if (command.OrderProperty.ToLower().Equals("asc"))
      {
         accessForms.Forms = accessForms.Forms.OrderBy(o => o.EmployeeName).ToList();
      }
      else
      {
         accessForms.Forms = accessForms.Forms.OrderByDescending(o => o.EmployeeName).ToList();
      }
      break;
   case "requestingemployeename":
         (...)

}

accessForms.FormsList<>。我想让这段代码更简洁更短,但我不知道如何实现。

【问题讨论】:

  • 这更适合codereview.stackexchange.com,因为您有工作代码。但我认为你至少可以在 switch 中创建 lamba 表达式,并在 switch 之外处理排序顺序。
  • 您不应该使用 TLower 但 ToUppad - .NET 针对上层比较进行了优化,而不是下层比较。 docs.microsoft.com/en-us/dotnet/standard/base-types/…
  • @TomTom 你也不应该使用。如果您想以不区分大小写的方式比较字符串,则应使用不区分大小写的比较器。

标签: c# .net


【解决方案1】:

以下应该可以工作,基本上是构建一个函数,从表单中提取排序字段并在 Linq 操作中使用它。

请注意,如果排序字段都是字符串,例如,您可以使用更强类型的 func。

Func<Form, object> sortFieldGetter = null;

switch (command.SortProperty.ToLower())
{
   case "number":
       sortFieldGetter = form => (object)form.NumberForSort;
       break;

   case "type":
       sortFieldGetter = form => (object)form.Type;
       break;

   case "employeename":
       sortFieldGetter = form => (object)form.EmployeeName;
       break;

   ...
}

if (command.OrderProperty.ToLower().Equals("asc"))
{
    accessForms.Forms = accessForms.Forms.OrderBy(sortFieldGetter).ToList();
}
else
{
    accessForms.Forms = accessForms.Forms.OrderByDescending(sortFieldGetter).ToList();
}

【讨论】:

    【解决方案2】:

    使用@rob 编写的here 代码,在您的情况下,最终代码可能如下所示:

     accessForms.Forms = command.OrderProperty.ToLower().Equals("asc")) ?
         accessForms.Forms.OrderBy(command.SortProperty.ToLower()).ToList() :
         accessForms.Forms.OrderByDescending(command.SortProperty.ToLower()).ToList();
    

    请注意,您需要实现您自己的 OrderByDescending,但原始代码中没有。

    【讨论】:

      【解决方案3】:

      我同意这个问题可能更适合代码审查。

      在任何情况下,您都可以按照以下方式做一些事情:

      第 1 步:创建扩展方法

      public static IQueryable<T> SortByField<T, TKey>(this IQueryable<T> source, Expression<Func<T, TKey>> selector, bool ascending = true)
      {
          return ascending ? source.OrderBy(selector) : source.OrderByDescending(selector);
      }
      
      public static IQueryable<T> SortByField<T, TKey>(this IQueryable<T> source, Expression<Func<T, TKey>> selector, string order = "asc")
      {
          return SortByField(source, selector, order.Equals("asc", StringComparison.OrdinalIgnoreCase)); //condition here can be improved, just as a sample of how to do it
      }
      

      第 2 步:享受:

       var samples = new List<Sample>().AsQueryable(); //you can of course use LINQ to SQL or EF, but I am lazy
       samples.SortByField(t => t.NumberForSort, false); //or "asc"
      

      我认为改进您的“命令”/查询对象将有助于清理代码。

      咆哮:“case”对我来说是最后的手段,它几乎总是意味着至少有两个地方我必须更改代码,它们可能并不总是位于同一个程序集中,并且几乎所有使用“case " 可以替换为 Dictionary 或 Strategy 模式。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-09-13
        • 2012-10-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-02-23
        • 1970-01-01
        相关资源
        最近更新 更多