C#递归获取对象的位置

C#递归获取对象的位置,c#,recursion,C#,Recursion,我有一个自引用的类。 IDModuleOpai是指向其父对象的键,ModulesFilhos是该对象的子对象 我有一个属性,defoundidade,它递归地计算该对象的深度 另一个重要属性是Ordem。它保存用户在该范围内定义的所需顺序 Id Nome IdModuloPai Ordem Profundidade OrdemGlobal 1 Root [NULL] 0 0 0 2

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

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

另一个重要属性是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的函数,它可以计算其全球位置。我正在尝试获取最后一列或emglobal。然后,我可以按OrdemGlobal对对象进行排序,它将始终以相同的方式出现在我需要的每个局部对象中

根据此表,正确的位置为

Root
    +Users
        +Administration
        +Logs
    +Customers
        +Orders
请注意,管理出现在日志之前,因为管理的Ordem=0,而日志的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;
    }
}
公共类模块模型
{
公共int Id{get;set;}
公共字符串Nome{get;set;}
公共int-Ordem{get;set;}
公共虚拟整数深度{
得到
{
返回GetDepth(this);
}
}
公共int?idModuleOpai{get;set;}
公共虚拟ModuleModel ModulePai{get;set;}
公共虚拟ICollection modulesFilhos{get;set;}
private int GetDepth(modulemodel modulemodel)
{
if(moduleModel==null)返回0;
if(modulemodel.idmoduleopai==null)返回0;
返回GetDepth(moduleModel.modulePai)+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;
    }
public virtual int或emglobal
{
得到
{
返回GetGlobalOrder(此);
}
}        
私有int GetGlobalOrder(模块模型模块模型)
{
if(moduleModel==null)返回0;
if(modulemodel.modulepai==null)返回0;
int smallerSiblings=modulemodel.modulepai.modulesFilhos.Where(x=>x.Ordem
但是这很混乱,并且没有返回所需的信息。

为什么不直接返回呢

return this.Ordem;
聚合根在哪里?类正在引用自身,因此它必须知道它有什么Ordem值。它不知道它上面的任何内容,只知道它的子项。

这里有一个
IComparer
,它按照您想要的顺序排序

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);
        }
    }
}
公共类模块模型比较器:比较器
{
公共覆盖整数比较(模模型x、模模型y)
{
//它们是相同的节点。
如果(x等于(y))
返回0;
//缓存这些值,这样我们就不需要额外执行GetDepth调用
var xProfundidade=x.深刻的;
变量yProfundidade=y.深部;
//查找共享父级
如果(xProfundidade>yProfundidade)
{
//x是y的孩子
如果(x.ModuloPai.等于(y))
返回1;
返回比较(x.ModuloPai,y);
}
else if(yProfundidade>xProfundidade)
{
//y是x的孩子
如果(x等于(y.ModuloPai))
返回-1;
返回比较(x,y.ModuloPai);
}
其他的
{
//它们共享一个父节点,但不是同一个节点,只需在Ordem上进行比较即可。
如果(x.ModuloPai.等于(y.ModuloPai))
返回x.Ordem.CompareTo(y.Ordem);
//他们是同一水平,但有不同的父母,上一层
返回比较(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;
    }
}
类测试
{
公共静态void Main()
{
var root=CreateModel(1,“root”,null,0);
var users=CreateModel(2,“用户”,根,0);
var管理=CreateModel(3,“管理”,用户,0);
var logs=CreateModel(4,“日志”,用户,1);
var客户=CreateModel(5,“客户”,根,0);
var orders=CreateModel(6,“订单”,客户,0);
列表=新列表{根、用户、管理、日志、客户、订单};
Sort(新的ModuleModelComparer());
foreach(列表中的var模块模型)
{
控制台写入线(modulemodel.Nome);
}
Console.ReadLine();
}
私有静态ModuleModel CreateModel(int-id、字符串Nome、ModuleModel-ModulePai、int-ordem)
{
var model=new modulemodel{Id=Id,Nome=Nome,idmoduleopai=moduleopai?.Id,moduleopai=moduleopai,modulesfilhos=new HashSet(),Ordem=Ordem};
ModulePai?.ModulesFilhos.Add(型号);
收益模型;
}
}

希望这足以让您走上正确的道路。

您能提供一个GetGlobalOrder返回的示例吗?