代码之家  ›  专栏  ›  技术社区  ›  leora Matt Lacey

如何清理此代码以消除重复?

  •  2
  • leora Matt Lacey  · 技术社区  · 14 年前

        private List<SelectListItem> GetDeskList(int deskId)
        {
            List<Desk> apps = Model.GetDesks();
    
            List<SelectListItem> dropdown = apps.ConvertAll(c => new SelectListItem
            {
                Selected = c.Id == deskId,
                Text = c.Name,
                Value = c.Id.ToString()
            }).ToList();
            dropdown.Insert(0, new SelectListItem());
            return dropdown;
        }
    
        private List<SelectListItem> GetRegionList(int regionId)
        {
            List<Region> apps = Model.GetRegions();
    
            List<SelectListItem> dropdown = apps.ConvertAll(c => new SelectListItem
            {
                Selected = c.Id == regionId,
                Text = c.Name,
                Value = c.Id.ToString()
            }).ToList();
            dropdown.Insert(0, new SelectListItem());
            return dropdown;
        }
    

    还有一些类似的图案。重构此文件以避免重复的最佳方法是什么

    5 回复  |  直到 14 年前
        1
  •  2
  •   LukeH    14 年前

    如果可以更改模型以实现公共接口(或从公共基类继承),则可以执行以下操作:

    var desks = GetList(123, () => Model.GetDesks());
    
    var regions = GetList(456, () => Model.GetRegions());
    
    // ...
    
    private List<SelectListItem> GetList<T>(int id, Func<List<T>> getApps)
        where T : IDropdownItem
    {
        List<T> apps = getApps();
    
        List<SelectListItem> dropdown = apps.ConvertAll(c => new SelectListItem
            {
                Selected = c.Id == id,
                Text = c.Name,
                Value = c.Id.ToString()
            }).ToList();
    
        dropdown.Insert(0, new SelectListItem());
        return dropdown;
    }
    
    public interface IDropdownItem
    {
        int Id { get; }
        string Name { get; }
    }
    
    public class Desk : IDropdownItem { /* ... */ }
    
    public class Region : IDropdownItem { /* ... */ }
    
        2
  •  4
  •   user177800 user177800    14 年前

    只是暗中捅了一刀,但像这样的事情是你应该去做的:

    private List<SelectListItem> GetList<T>(List<T> list, int Id)
    {
        List<SelectListItem> dropdown = list.ConvertAll(c => new SelectListItem
        {
            Selected = c.Id == Id,
            Text = c.Name,
            Value = c.Id.ToString()
        }).ToList();
        dropdown.Insert(0, new SelectListItem());
        return dropdown;
    }
    

    并传递类型安全列表,而不是调用 GetList 方法

        3
  •  1
  •   Mau    14 年前
    private List<SelectListItem> GetObjectList<ObjectType>(int id, Func<List<ObjectType>> getObjects)
    {
        List<ObjectType> apps = getObjects();
    
        List<SelectListItem> dropdown = apps.ConvertAll(c => new SelectListItem
        {
            Selected = c.Id == id,
            Text = c.Name,
            Value = c.Id.ToString()
        }).ToList();
        dropdown.Insert(0, new SelectListItem());
        return dropdown;
    }
    
    private List<SelectListItem> GetDeskList(int deskId)
    {
        return GetObjectList(deskId, (() -> Model.GetDesks()));
    }
    
    private List<SelectListItem> GetRegionList(int regionId)
    {
        return GetObjectList(regionId, (() -> Model.GetRegions()));
    }
    
        4
  •  0
  •   AShelly    14 年前

    也许在列表项类型上模板化函数,然后传入列表?

    private List<SelectListItem, ItemType> GetRegionList(int theId, List<ItemType> apps) 
    { 
         List<SelectListItem> dropdown = apps.ConvertAll(c => new SelectListItem 
        { 
            Selected = c.Id == theId, 
            Text = c.Name, 
            Value = c.Id.ToString() 
        }).ToList(); 
        dropdown.Insert(0, new SelectListItem()); 
        return dropdown; 
    } 
    
    List<Desk> apps = Model.GetDesks();
    GetRegionList<SelectListItem,Desk>(ID, apps);
    
        5
  •  0
  •   Ryk    14 年前