2013-03-30 42 views
0

以下代码的设计使得如果更改分配给一个节点的数组,它不会影响其他节点。将数组存储在c#数据结构中,使其具有类似于数值结构的行为

我的问题是:是否有一个更“地道”的方式来完成这个?

void Main() 
{ 
    var arr = new [] { 1, 2, 3 }; 

    var node1 = new Node(); 
    node1.Children = arr; 

    var node2 = new Node(); 
    node2.Children = arr; 

    node1.Children[0] = 9; // node2 SHOULD NOT be affected by this 

    node1.Dump(); 
    node2.Dump(); 
} 

class Node 
{ 
    private int[] children; 

    public int[] Children 
    { 
     get { return children; } 
     set 
     { 
      children = new int[value.Length]; 
      value.CopyTo(children, 0); 
     } 
    } 
} 
+0

为什么要公开阵列?考虑一下'List'或者其他一些集合......甚至是'IEnumerable'。数组很难跟踪,因为您可以修改现有数组中的值。你的示例看起来像你试图构建不可变树 - 暴露阵列不会削减它。 –

+0

我不会推荐*那*特殊的方法。想想最不惊奇的原则。我会发现它非常令人惊讶,看到Main中的代码不会导致Node的每个实例中的数组的第一个元素具有9作为值。我可能会选择完全封装数组并将方法暴露出来。 –

+0

是否“节点”对现有“模板”的引用时间尽可能长,然后仅在需要时才创建_copy_?例如为了记忆的目的?我至少要在'Node'上创建一个属性,用于指示底层存储是否为_the_模板,例如'IsStillUsingTemplate'(需要在您的'Children'' set'处设置为'FALSE')。如果可行的话,我会创建一个获得'增强'存储的方法,因此调用者必须在测试'IsStillUsingTemplate'后明确地做到这一点(但如果它需要透明,可能会破坏你想做的事情)。 – Sepster

回答

3

这个将帖子什么:

class Node 
{ 
    private int[] _children; 

    public Node(int[] children) 
    { 
     this._children = (int[])children.Clone();//HERE IS THE IDEA YOU ARE LOOKING FOR 
    } 

    public int this[int index] 
    { 
     get { return this._children[index]; } 
     set { this._children[index] = value; } 
    } 
} 
+0

+0:克隆可能更好(至少更短)的方式复制一个数组......我也只是使用'value.ToArray();'...但暴露数组作为'get'中的数组看起来不看像好的建议(即使OP的样本显示它)。 –

+0

感谢您的回答。如果只有C#让你重载赋值运算符,那将是完美的。 –

0

我想你会过得更好改变数组对象拷贝语义,而不是增加功能的节点类,以支持这一点。幸运的是,已经有一个包含您正在寻找的语义的类:List。

这简化了节点类:

class Node 
{ 
    public List<int> Children { get; set; } 
} 

结果:

static void Main(string[] args) 
{ 
    var arr = new[] { 1, 2, 3 }; 

    var node1 = new Node 
    { 
     Children = new List<int>(arr) 
    }; 

    var node2 = new Node 
    { 
     Children = new List<int>(node1.Children) 
    }; 

    node1.Children[0] = 9; // node2 SHOULD NOT be affected by this 

    Console.WriteLine("First element node1:{0}, first element node2:{1}", 
     node1.Children[0], node2.Children[0]);    
} 
+0

+0。我还没有看到这种方法比简单的方法好得多,比如'public readonly List Children = new List ();'...加上它仍然不清楚为什么OP需要一个阵列来暴露... –

+0

Doah !你当然是对的。我改变了我的答案。我不同意公开阵列本身就是不好的做法,但显然这种情况并不适合。 –

+0

我的问题的上下文是我试图制作一个基本上具有值语义的节点数据结构(每个引用都指向一个新副本)。当我意识到没有拷贝构造函数时,我有点死路一条。 –

相关问题