如何通过构造函数正确初始化两个类之间的父子引用 [英] How properly initialize parent and child references between two classes through constructor

查看:24
本文介绍了如何通过构造函数正确初始化两个类之间的父子引用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两节课.第一类是 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆