简体   繁体   中英

Generic sorting of hierarchical data in c#

I am trying to sort a list of objects that have hierarchical form of n depth. Below I have the code for one of my cases which I am trying to sort using generic method because I have many hierarchical entities in my system

public class Company
{
    public int Id { get; set; }

    public string Name { get; set; }

    public int? ParentId { get; set; }

    public List<Company> Subsidiaries { get; set; } = new List<Company>();
}

public class CompaniesService
{
    private readonly MyDbContext dbContext;

    public CompaniesService(MyDbContext dbContext)
    {
        this.dbContext = dbContext;
    }

    public List<Company> GetCompanies()
    {
        List<Company> sortedCompanies = dbContext.Companies.ToList().Sort(x => x.Name);
        return sortedCompanies;
    }
}

public static class Extensions
{

    public static List<T> Sort<T, K>(this List<T> list, Func<T, K> sortSelector)
    {
        List<T> result = list.OrderBy(sortSelector).ToList();

        foreach (T listItem in list)
        {
            if (listItem.Children.Count > 0)
                listItem.Children = Sort<T, K>(listItem.Children, sortSelector(listItem));
        }
        return result;
    }
}

How can I make the above work? I pass the initial data list that I receive from database but how can I do recursion to sort children (in the above scenario subsidiaries)? The code above is not compiling with Error mentioned below.

'T' does not contain a definition for 'Children' and no accessible extension method 'Children' accepting a first argument of type 'T' could be found (are you missing a using directive or an assembly reference?)

Does this work for you?

public interface IHierarchy<T>
{
    List<T> Children { get; set; }
}

public class Company : IHierarchy<Company>
{
    public int Id { get; set; }

    public string Name { get; set; }

    public int? ParentId { get; set; }

    public List<Company> Subsidiaries { get; set; } = new List<Company>();

    List<Company> IHierarchy<Company>.Children
    {
        get => this.Subsidiaries;
        set => this.Subsidiaries = value;
    }
}

public static class Extensions
{

    public static List<T> Sort<T, K>(this List<T> list, Func<T, K> sortSelector) where T : IHierarchy<T>
    {
        List<T> result = list.OrderBy(sortSelector).ToList();

        foreach (T listItem in list)
        {
            if (listItem.Children.Count > 0)
                listItem.Children = Sort<T, K>(listItem.Children, sortSelector);
        }
        return result;
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM