给定这样的一个对象
问题在于用户创建的“事物”没有防止乱伦关系(即父母可以有子女(他们又可以有子女等等...最终指向父母)。可以在数据库中对其进行约束以防止事物不成为自己的父母(有意义),但是根据深度,这可能会变得很丑陋,并且有人认为可能需要循环引用(我们仍在讨论中...)
因此,可以说这些结构是循环的,但是如果您想在网页上呈现这种结构,例如在父/子菜单中作为
.NET fiddle here
public class Thing
{
public Thing() { this.children = new List<Thing>();}
public int Id {get; set;}
public string Name {get; set;}
public List<Thing> children{ get; set;}
public string ToString(int level = 0)
{
//Level is added purely to add a visual hierarchy
var sb = new StringBuilder();
sb.Append(new String('-',level));
sb.AppendLine($"id:{Id} Name:{Name}");
foreach(var child in children)
{
sb.Append(child.ToString(level + 1));
}
return sb.ToString();
}
}
如果以这种方式使用(滥用?),
public static void Main()
{
var root = new Thing{Id = 1,Name = "Thing1"};
var thing2 = new Thing{Id = 2,Name = "Thing2"};
var thing3 = new Thing{Id = 3,Name = "Thing3"};
root.children.Add(thing2);
thing2.children.Add(thing3);
thing3.children.Add(root); //problem is here
Console.WriteLine(root.ToString());
}
如何在这种情况下采取防御性措施。
目前的代码会产生一个stackoverflow、无限递归或内存溢出错误。
在(IIS)网站中,这会导致w3工作进程崩溃,并最终使应用程序池关闭(快速故障保护)。
上面的代码仅表示重现问题所需。在实际情况中,结构来自具有Id和ParentId的数据库。
数据库表结构类似于:
CREATE TABLE Thing(
Id INT NOT NULL PRIMARY KEY,
Name NVARCHAR(255) NOT NULL,
ParentThingId INT NULL //References self
)
问题在于用户创建的“事物”没有防止乱伦关系(即父母可以有子女(他们又可以有子女等等...最终指向父母)。可以在数据库中对其进行约束以防止事物不成为自己的父母(有意义),但是根据深度,这可能会变得很丑陋,并且有人认为可能需要循环引用(我们仍在讨论中...)
因此,可以说这些结构是循环的,但是如果您想在网页上呈现这种结构,例如在父/子菜单中作为
<ul><li><a>
标签之类的东西,如何在代码中积极处理此类用户生成的数据问题?.NET fiddle here