C#以递归方式获取对象的位置

时间:2016-11-10 15:58:45

标签: c# recursion

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

我有一个属性 Profundidade ,它以递归方式计算该对象的深度。

另一个重要的属性是 Ordem 。它保存用户在该范围内定义的所需顺序。

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

请看这个示例表。

我正在尝试创建一个类似于Profundidade的函数,它计算了它的全球位置。我正在努力获得最后一栏 OrdemGlobal 。然后,我可以通过OrdemGlobal订购对象,它将在我需要的每个地方以相同的方式出现。

根据此表,正确的位置是

Root
    +Users
        +Administration
        +Logs
    +Customers
        +Orders

在日志之前查看管理层是否存在因为管理具有Ordem = 0且Logs具有Ordem = 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;
    }
}

编辑:改进问题

我尝试过像

这样的东西
    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;
    }

但这很困惑,并没有返回所需的信息。

2 个答案:

答案 0 :(得分:1)

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

希望这足以让你走上正轨。

答案 1 :(得分:0)

为什么不返回

return this.Ordem;

聚合根在哪里?这个类指的是它自己,所以它必须知道它有什么Ordem值。它不知道它上面的任何东西,只有它的孩子。