2017-05-25 59 views
1
var board = Enumerable.Repeat(Enumerable.Repeat('.', 3).ToArray(), 3).ToArray(); 
board[0][0] = 'Q'; 

這裏我試圖創建數組(3 * 3)數組填充相同的元素。 但是,當我嘗試更改一個元素([0,0])時,它會更改所有三個數組中的第一個元素。爲什麼會這樣,以及如何修復這種行爲,而無需2個循環來啓動數組?初始化陣列填充相同的元素

+0

是不是有一個原因,你沒有宣佈董事會作爲一個數組從起點?也許如果你這樣做,你可以聲明你想要到達哪個數組。 –

+0

@EthanTheBrave如果OP將它聲明爲'char [] [] board'並不重要,'var'處理它是一樣的。 –

回答

1

Enumerable.Repeat()返回你給它的東西。它不會每次都創建一個新的副本。

內部Enumerable.Repeat()返回字符'。'三次。字符是「價值型」,也就是說這將創建字符「Y」的新副本:

char x = 'y'; 

當你將它不能創造價值類型的副本。

但是數組是一個引用類型,並且規則是不同的。外部Enumerable.Repeat()返回三次相同的數組對象。你沒有通過三次創建新陣列的指令。你傳遞一個對現有數組的引用,並說「給我三次這樣的事情」。而不像一個角色,再次給你相同的數組不會創建它的副本。

陣列是一個「引用類型」,也就是說,低於第二行創建一個新參考到相同對象

char[] a = new [] { 'a', 'b', 'c' }; 
var y = a; 

ay同一對象。如果您設置了a[0] = 'd';,則可以使用參考y來查看相同的數組對象,並在[0]中看到相同的字母'd'。

Enumerable.Repeat() x次返回相同的東西。如果你想創建一個值類型的多個實例,那不是你想要的。

這是你想要什麼,如果你想的Linq:

var board = Enumerable.Range(0, 3) 
      .Select(n => Enumerable.Repeat('.', 3).ToArray()) 
      .ToArray(); 

Select()執行每次代碼,所以你執行的代碼每次可以創建一個新的數組。 Repeat()只是不斷返回你給它的任何價值。

2

因爲你創建了一個數組Enumerable.Repeat('.', 3).ToArray()並且克隆了這個數組的引用3次。 所以,你有3個參考到一個值。 需要初始化的每一行:

var board = Enumerable.Repeat((char[])null, 3).ToArray(); 
for (int i = 0; i < 3; i++) 
{ 
    board[i] = Enumerable.Repeat('.', 3).ToArray(); 
} 
board[0][0] = 'Q';