c#递归地获取对象的位置

本文关键字:位置 取对象 获取 递归 | 更新日期: 2023-09-27 18:17:22

我有一个自我引用的类。IdModuloPai是指向父对象的键, modulofilhos 是该对象的子对象。

我有一个属性, profunddidade ,它递归地计算对象的深度。

另一个重要属性是 order 。它保存了用户在该作用域中定义的所需顺序。

Id  Nome            IdModuloPai Ordem   Profundidade    OrdemGlobal
1   Root            [NULL]      0       0               0
2   Users           1           0       1               1
3   Administration  2           0       2               2
4   Logs            2           1       2               3
5   Customers       1           0       1               4
6   Orders          5           0       2               5

看这个示例表。

我正在尝试创建一个类似于profunddidade的函数,计算其全局位置。我试图得到最后一列OrdemGlobal。然后,我可以通过orderglobal来排序对象,并且它将始终以相同的方式出现在我需要的每个局部。

根据这个表,正确的位置是

Root
    +Users
        +Administration
        +Logs
    +Customers
        +Orders

查看"Administration"出现在"Logs"之前,因为"Administration"的"orderm = 0"answers"Logs"的"orderm = 1"

我如何存档期望的行为?

我的类的代码如下

public class ModuloModel
{
    public int Id { get; set; }
    public string Nome { get; set; }
    public int Ordem { get; set; }
    public virtual int Profundidade { 
        get
        {
            return GetDepth(this);
        }
    }
    public int? IdModuloPai { get; set; }
    public virtual ModuloModel ModuloPai { get; set; }
    public virtual ICollection<ModuloModel> ModulosFilhos { get; set; }
    private int GetDepth(ModuloModel moduloModel)
    {
        if (moduloModel == null) return 0;
        if (moduloModel.IdModuloPai == null) return 0;
        return GetDepth(moduloModel.ModuloPai) + 1;
    }
}

EDIT:改进问题

我试过像

    public virtual int OrdemGlobal
    {
        get
        {
            return GetGlobalOrder(this);
        }
    }        
    private int GetGlobalOrder(ModuloModel moduloModel)
    {
        if (moduloModel == null) return 0;
        if (moduloModel.ModuloPai == null) return 0;
        int smallerSiblings = moduloModel.ModuloPai.ModulosFilhos.Where(x => x.Ordem < moduloModel.Ordem).Count();
        return (GetGlobalOrder(moduloModel.ModuloPai) + smallerSiblings + 1;
    }

但是这是混乱的,并且没有返回所需的信息。

c#递归地获取对象的位置

这是一个按您想要的顺序排序的IComparer<ModuloModel>

public class ModuloModelComparer : Comparer<ModuloModel>
{
    public override int Compare(ModuloModel x, ModuloModel y)
    {
        //They are the same node.
        if (x.Equals(y))
            return 0;
        //Cache the values so we don't need to do the GetDepth call extra times
        var xProfundidade = x.Profundidade;
        var yProfundidade = y.Profundidade;
        //Find the shared parent
        if (xProfundidade > yProfundidade)
        {
            //x is a child of y
            if (x.ModuloPai.Equals(y))
                return 1;
            return Compare(x.ModuloPai, y);
        }
        else if (yProfundidade > xProfundidade)
        {
            //y is a child of x
            if (x.Equals(y.ModuloPai))
                return -1;
            return Compare(x, y.ModuloPai);
        }
        else
        {
            //They both share a parent but are not the same node, just compare on Ordem.
            if (x.ModuloPai.Equals(y.ModuloPai))
                return x.Ordem.CompareTo(y.Ordem);
            //They are the same level but have diffrent parents, go up a layer
            return Compare(x.ModuloPai, y.ModuloPai);
        }
    }
}

下面是一个使用它的测试程序

class Test
{
    public static void Main()
    {
        var root = CreateModel(1, "Root", null, 0);
        var users = CreateModel(2, "Users", root, 0);
        var administration = CreateModel(3, "Administration", users, 0);
        var logs = CreateModel(4, "Logs", users, 1);
        var customers = CreateModel(5, "Customers", root, 0);
        var orders = CreateModel(6, "Orders", customers, 0);

        List<ModuloModel> list = new List<ModuloModel> {root, users, administration, logs, customers, orders};
        list.Sort(new ModuloModelComparer());
        foreach (var moduloModel in list)
        {
            Console.WriteLine(moduloModel.Nome);
        }
        Console.ReadLine();
    }
    private static ModuloModel CreateModel(int id, string Nome, ModuloModel moduloPai, int ordem)
    {
        var model = new ModuloModel {Id = id, Nome = Nome, IdModuloPai = moduloPai?.Id, ModuloPai = moduloPai, ModulosFilhos = new HashSet<ModuloModel>(), Ordem = ordem};
        moduloPai?.ModulosFilhos.Add(model);
        return model;
    }
}

为什么不直接返回

return this.Ordem;

聚合根在哪里?类引用自己,所以它必须知道自己的order值。它不知道上面的任何东西,只知道它的子元素