模拟C++;C#中的友谊与部分类
我有以下情况: 我需要创建一个树型结构,一旦实例化,它是不可变的。问题是,在构建过程中,我需要能够插入节点。因此,我需要某种允许插入节点的私有接口,而这种结构的公共接口只允许检索节点。我试过这个:模拟C++;C#中的友谊与部分类,c#,partial-classes,C#,Partial Classes,我有以下情况: 我需要创建一个树型结构,一旦实例化,它是不可变的。问题是,在构建过程中,我需要能够插入节点。因此,我需要某种允许插入节点的私有接口,而这种结构的公共接口只允许检索节点。我试过这个: public partial class TreeLike { public SomeType1 SomeTreeProperty1 { get; private set; } public SomeType2 SomeTreeProperty2 { get; private set; }
public partial class TreeLike {
public SomeType1 SomeTreeProperty1 { get; private set; }
public SomeType2 SomeTreeProperty2 { get; private set; }
private List<NodeLike> _Nodes = new List<NodeLike>();
public ReadOnlyCollection<NodeLike> Nodes {
get {
return _Nodes.AsReadOnly();
}
}
}
public class NodeLike {
public SomeType1 SomeNodeProperty { get; private set; }
private List<NodeLike> _Children = new List<NodeLike>();
public ReadOnlyCollection<NodeLike> Children {
get {
return _Children.AsReadOnly();
}
}
public partial class TreeLike {
public SomeType3 SomeTreeProperty3 { get; private set; }
TreeLike() {
NodeLike n0 = new NodeLike();
NodeLike n1 = new NodeLike();
n0._Children.Add(n1);
_Nodes.Add(n0);
}
}
}
公共部分类树状结构{
public SomeType1 SomeTreeProperty1{get;private set;}
public SomeType2 SomeTreeProperty2{get;private set;}
私有列表_节点=新列表();
公共只读集合节点{
得到{
返回_Nodes.AsReadOnly();
}
}
}
公共类节点{
public SomeType1 SomeNodeProperty{get;private set;}
私有列表_Children=新列表();
公共只读集合子项{
得到{
return_Children.AsReadOnly();
}
}
公共部分类树状{
public SomeType3 SomeTreeProperty3{get;private set;}
树状的{
NodeLike n0=新的NodeLike();
NodeLike n1=新的NodeLike();
n.添加子项(n1);
_添加(n0);
}
}
}
这个问题(除了在NodeLike
中继续使用TreeLike
的声明/定义有点骇人听闻之外)是,当它工作时,TreeLike
的某些树属性3
对外部世界是看不见的。也就是说,如果我在最外面的作用域创建一个树状的实例,我只能访问第一个在分部类的“全局”作用域声明中声明的属性
因此,我想知道是否有办法使分部类的嵌套延续中声明的属性和方法对全局范围(以及该类的客户机)仍然可见。或者,如果不是,还有什么更好的C#惯用方式?
可能会创建类的不可变版本?针对您的设计需求的可能解决方案如下所示:
public partial class TreeLike {
public SomeType1 SomeTreeProperty1 { get; private set; }
public SomeType2 SomeTreeProperty2 { get; private set; }
public SomeType3 SomeTreeProperty3 { get; private set; }
private List<NodeLike> _Nodes = new List<NodeLike>();
public ReadOnlyCollection<NodeLike> Nodes {
get {
return _Nodes.AsReadOnly();
}
}
TreeLike() {
NodeLike n1 = new NodeLike();
NodeLike n0 = new NodeLike(n1);
_Nodes.Add(n0);
}
}
public class NodeLike {
public SomeType1 SomeNodeProperty { get; private set; }
private List<NodeLike> _Children = new List<NodeLike>();
public ReadOnlyCollection<NodeLike> Children {
get {
return _Children.AsReadOnly();
}
public NodeLike(params NodeLike[] children) {
_Children = children.ToList();
}
}
new NodeLike(childNode1, childNode2, childNode3);
interface INode
{
public string Name { get; }
public ReadOnlyCollection<INode> Children { get; }
}
旁注:大括号是。您只需在构造函数内执行所有初始化,因为它允许您使用只读字段实现真正的不变性
例如,如果节点接口的定义如下:
public partial class TreeLike {
public SomeType1 SomeTreeProperty1 { get; private set; }
public SomeType2 SomeTreeProperty2 { get; private set; }
public SomeType3 SomeTreeProperty3 { get; private set; }
private List<NodeLike> _Nodes = new List<NodeLike>();
public ReadOnlyCollection<NodeLike> Nodes {
get {
return _Nodes.AsReadOnly();
}
}
TreeLike() {
NodeLike n1 = new NodeLike();
NodeLike n0 = new NodeLike(n1);
_Nodes.Add(n0);
}
}
public class NodeLike {
public SomeType1 SomeNodeProperty { get; private set; }
private List<NodeLike> _Children = new List<NodeLike>();
public ReadOnlyCollection<NodeLike> Children {
get {
return _Children.AsReadOnly();
}
public NodeLike(params NodeLike[] children) {
_Children = children.ToList();
}
}
new NodeLike(childNode1, childNode2, childNode3);
interface INode
{
public string Name { get; }
public ReadOnlyCollection<INode> Children { get; }
}
(相对于私人)不做你想做的吗?你是什么意思?保护名单?这些类没有继承关系。我误解你了吗?为什么不给NodeLike
一个构造函数,它接受另一个NodeLike
并将其作为子类添加?TreeLike
和NodeLike。TreeLike
是两个不同的类。partial
修饰符在这种情况下不起任何作用。对不起,我把protected与混淆了。有没有理由不起作用?