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