2017-05-25 89 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';