Search code examples
c#refactoringcode-duplication

How can this code be cleaned up to remove duplication?


i have the following code which has some duplication

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

and a few more like it with a similar pattern. what is the best way to refactor this to avoid duplication


Solution

  • If you can change your models to implement a common interface (or inherit from a common base class) then you might be able to do something like this:

    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 { /* ... */ }