2013-03-30 32 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

我的問題的上下文是我試圖製作一個基本上具有值語義的節點數據結構(每個引用都指向一個新副本)。當我意識到沒有拷貝構造函數時,我有點死路一條。 –