如何通过构造函数正确初始化两个类之间的父子引用 [英] How properly initialize parent and child references between two classes through constructor
问题描述
我有两节课.第一类是 Parent
,它具有对象列表( Child
).每个 Child
都具有对其 Parent
类的引用.问题是如何通过构造函数实现此引用.
I have two classes. First class is Parent
, which has a list of objects (Child
). Each of the Child
has the reference to his Parent
class. Question is how to implement this reference through the constructor.
public sealed class Child
{
public Child(string id, string name, Parent parent)
{
Id = id;
Name = name;
Parent = parent;
}
public Parent ParentInstance { get; private set; }
public string Id { get; private set; }
public string Name { get; private set; }
}
public sealed class Parent
{
public Parent(string id, string name, IEnumerable<Child> children)
{
Id = id;
Name = name;
Children = children;
}
public string Id { get; private set; }
public string Name { get; private set; }
public IEnumerable<Child> Children { get; private set; }
}
问题是我有一个解析一些XML代码并创建 Parent
对象列表的代码.这是示例:
The issue is that I have a code which parses some XML code and creates the list of Parent
objects. Here is the example:
internal Parent ParseParent(XElement parentXElement)
{
return new Parent(parentXElement.Attribute("id").Value, parentXElement.Attribute("name").Value, parentXElement.Descendants("child").Select(ParseChild));
}
我当然可以在 Parent
构造函数中初始化 Parent
属性,只需从 Parent
设置器中删除 private
然后穿越所有孩子并使用此属性.但我想将其设置为只读.像这样:
Of course I can init the Parent
property within Parent
constructor, just remove the private
from Parent
setter and then go trhough all children and use this property. But I want to make it read-only. Something like this:
public Parent(string id, string name, IEnumerable<Child> children)
{
Id = id;
Name = name;
Children = children.ForEach(c => c.ParentInstance = this);
}
推荐答案
要成为不可变的 并包含循环引用,您需要以下内容:
To be immutable and include cyclic references, you'd need something like this:
public sealed class Parent
{
private readonly IEnumerable<Child> children;
private readonly string name; // Just for example
public Parent(XElement element)
{
name = (string) element.Attribute("name");
children = element.Elements("Child")
.Select(x => new Child(x, this))
.ToImmutableList(); // Or whatever collection you want
}
}
public sealed class Child
{
private readonly Parent parent;
private readonly string name; // Just for example
public Child(XElement element, Parent parent)
{
this.name = (string) element.Attribute("name");
// Better not ask the parent for its children yet - they won't be
// initialized!
this.parent = parent;
}
}
Child
构造函数中的注释应该引起您的注意.即使 Parent
是不可变的,我们也要在完成初始化之前泄漏 this
...因此, Child
构造函数需要确保它不会在构建过程中尝试找到其兄弟姐妹.
The comment in the Child
constructor is the bit that should make you raise your eyebrows. Even though Parent
is immutable, we're leaking this
before we've finished initializing it... so the Child
constructor needs to make sure it doesn't try to find its siblings during construction.
这篇关于如何通过构造函数正确初始化两个类之间的父子引用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!