我经常发现自己经常写一个“父母”和“孩子”的数据结构,其中:
private
),违反上述规则是不可能的。在实现类似这样的事情之前,人们可能会采取的心理步骤可能从以下内容开始:
public class Parent
{
private readonly List<Child> _children = new List<Child>();
public readonly ReadOnlyCollection<Child> Children = _children.AsReadOnly();
}
public class Child
{
private Parent _parent;
public Parent Parent
{
get
{
return _parent;
}
set
{
if(value == _parent)
return;
if(_parent != null)
{
_parent._children.Remove(this);
_parent = null;
}
if(value != null)
{
value._children.Add(this);
_parent = value;
}
}
}
}
当然,这不会编译,因为Parent._children
是private
。但是,您不希望将其设为私有内容,因为允许在Child
或Parent
之外进行访问会导致违反实施规则或其他地方的规则。
因此,我提出的解决方案是将Child
嵌套在Parent
中。嵌套类可以访问嵌套在其中的类的私有成员:
public class Parent
{
private readonly List<Child> _children = new List<Child>();
public readonly ReadOnlyCollection<Child> Children = _children.AsReadOnly();
public class Child
{
private Parent _parent;
public Parent Parent
{
get
{
return _parent;
}
set
{
if(value == _parent)
return;
if(_parent != null)
{
_parent._children.Remove(this);
_parent = null;
}
if(value != null)
{
value._children.Add(this);
_parent = value;
}
}
}
}
}
我问的问题是,有没有其他方法可以实现相同的目标,这种方法比这种方法有更少或更少的重要缺点?我发现这种方法的主要缺点是:
partial
可以提供帮助。Child
之外访问Parent
,您必须使用Parent.Child
。如果类名很长,特别是使用泛型时,这会导致代码非常难看。Child
是嵌套的,Parent<T1>.Child
是与Parent<T2>.Child
不同的类型,当你希望类型安全是相互的时,这可能会导致非常丑陋使用泛型,或者需要回退到使用运行时强制类型的安全性(尽管它可以被封装掉,通常,例如,使用非public
访问者protected
的非通用抽象基础另外,这可能是使用friend
扩展访问权限可以简化这些问题的一个很好的例子!
答案 0 :(得分:2)
我喜欢使用通用的私有接口来公开这样的属性:
public class SomeBigOuterClass {
private interface IChildFriend {
void SetParent(Parent parent);
}
public class Parent {
}
public class Child : IChildFriend {
void IChildFriend.SetParent(Parent parent) {
this.parent = parent;
}
private Parent parent;
}
}
答案 1 :(得分:1)
正如我在评论中所说,在父母中添加一个删除方法,这至少不会暴露整个子列表。类似的东西:
public class Parent
{
private readonly List<Child> _children = new List<Child>();
public readonly ReadOnlyCollection<Child> Children = _children.AsReadOnly();
public void Remove(Child child)
{
if(child !=null)
{
_children.Remove(child);
}
}
}
答案 2 :(得分:0)
当然,正如评论和之前的回答中所述,您还需要封装将子项添加到父级,这需要公共Option Explicit
Sub test()
Dim filename As String
filename = "myFile2.xlsm"
Workbooks.Open filename:="C:\temp\myFile2.xlsm"
Workbooks.Open filename:="C:\temp\myFile1.xlsm"
Sheets("Sheet1").Copy After:=Workbooks(filename).Sheets(1)
End Sub
方法