Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/codeigniter/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在子项上自动设置父项引用_C# - Fatal编程技术网

C# 在子项上自动设置父项引用

C# 在子项上自动设置父项引用,c#,C#,我有一个类,它包含一个名为Children的IList属性。每个子级都应引用其父级。我的解决方案是在ParentClass.Childrengetter中设置ChildClass.Parent属性。有没有更好的方法,或者这是最好的解决方案 class ParentClass { private IList<ChildClass> _children; public virtual IList<ChildClass> Children {

我有一个类,它包含一个名为
Children
IList
属性。每个子级都应引用其父级。我的解决方案是在
ParentClass.Children
getter中设置
ChildClass.Parent
属性。有没有更好的方法,或者这是最好的解决方案

class ParentClass
{
    private IList<ChildClass> _children;

    public virtual IList<ChildClass> Children
    {
        get
        {
            // make sure each child refers to its parent (this)
            foreach (ChildClass c in _children)
            {
                c.Parent = c.Parent ?? this;
            }
            return _children;
        }
        set
        {
            _children = value;
        }
    }
}
class父类
{
私人儿童;
公共虚拟现实主义儿童
{
得到
{
//确保每个子级都引用其父级(此)
foreach(儿童c类儿童)
{
c、 父项=c。父项??此项;
}
返回儿童;
}
设置
{
_儿童=价值;
}
}
}

可能就是我……但这看起来像是个糟糕的设计

如果这是一种真正的父子关系,你不应该允许任何人创造一个孤儿。因此,应在创建时对子级设置父级

我可能会这样做:

class ChildClass
{
    private ParentClass _parent;

    public ChildClass(ParentClass parent)
    {
        _parent = parent;
    }
}
然后:

class ParentClass
{
    private List<ChildClass> _children;

    public virtual ReadOnlyCollection<ChildClass> Children
    {
        get
        {
            return _children.AsReadOnly();
        }
    }

    public virtual ChildClass CreateChild()
    {
        // Set parent in child class constructor
        ChildClass newChild = new ChildClass(this);

        _children.Add(newChild);

        return newChild;
    }
}
class父类
{
私人名单——儿童;
公共虚拟只读集合子项
{
得到
{
return_children.AsReadOnly();
}
}
公共虚拟子类CreateChild()
{
//在子类构造函数中设置父类
ChildClass newChild=新的ChildClass(本);
_添加(newChild);
返回新孩子;
}
}

解决方案的问题在于,如果所有子项和父项都正确链接,则每次检索内部子项集合时,代码都会重新链接它们。此外,这个问题的存在似乎是因为您正在返回对私有集合的引用,之后您将失去对它所包含元素的控制

我建议如下:

ParentClass
上提供
Add(ChildCLass)
Remove(ChildCLass)
方法,并在那里强制父子约束。这允许在任何位置创建子对象,并在属于层次结构时正确链接。从层次结构中删除后,将不再链接

除非集合是不可变的,否则不要返回对内部
ChildClass
集合的引用。最好返回
ReadOnlyCollection
IEnumerable

示例:

class ChildClass
{
    // Prevent unauthorized clients from overriding the Parent reference.
    public ParentClass Parent { get; internal set; }

    // ... other methods and properties ...
}

class ParentClass
{
    private IList<ChildClass> _children;

    public void AddChild(ChildClass child)
    {
        _children.Add(child);
        child.Parent = this;
    }

    public RemoveChild(ChildClass child)
    {
        _children.Remove(child);
        child.Parent = null;
    }

    public IList<ChildClass> Children
    {
        get { return _children.AsReadOnly(); }
    }
}
class子类
{
//防止未经授权的客户端重写父引用。
公共父类父{get;内部集;}
//…其他方法和属性。。。
}
类父类
{
私人儿童;
public void AddChild(ChildClass child)
{
_添加(child);
child.Parent=this;
}
公共RemoveChild(儿童级儿童)
{
_儿童。移除(儿童);
child.Parent=null;
}
公营儿童
{
获取{return _children.AsReadOnly();}
}
}

除非有其他人使用您的API。那种乐于做出极端概括的心态,比如“没有父对象,子对象永远不可能存在”,并将这种心态强加于其他程序员身上,这可能会导致一些开发人员在现实世界的边缘案例场景中经历数小时的痛苦和挫折。