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;
}
但是这是混乱的,并且没有返回所需的信息。
这是一个按您想要的顺序排序的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值。它不知道上面的任何东西,只知道它的子元素