var board = Enumerable.Repeat(Enumerable.Repeat('.', 3).ToArray(), 3).ToArray();
board[0][0] = 'Q';
这里我试图创建填充相同元素的数组(3 * 3)。 但是当我尝试更改一个元素([0,0])时,它会更改所有三个数组的第一个元素。为什么这样,如果没有2个循环来启动数组,如何解决这个问题呢?
答案 0 :(得分: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';
答案 1 :(得分:1)
Enumerable.Repeat()
会返回您提供的内容。它不会每次都创建它的新副本。
内部Enumerable.Repeat()
会返回字符&#39;。&#39;三次。字符是&#34;值类型&#34;,这意味着这会创建字符的新副本&#39; y&#39;:
char x = 'y';
分配时,您无法 创建值类型的副本。
但是数组是引用类型,规则是不同的。外Enumerable.Repeat()
返回相同的数组对象三次。您没有传递三次创建新阵列的指令。你传递了对现有数组的引用,然后说&#34;给我那个东西,三次&#34;。与角色不同,再次为您提供相同的阵列并不会创建它的副本。
数组是&#34;引用类型&#34;,这意味着下面的第二行为同一个对象创建了一个新的引用:
char[] a = new [] { 'a', 'b', 'c' };
var y = a;
a
和y
是同一个对象。如果您设置了a[0] = 'd';
,则可以使用引用y
查看同一个数组对象,并且您将看到相同的字母&#39; d&#39;在[0]
。
Enumerable.Repeat()
返回相同的内容x次。如果您尝试创建值类型的多个实例,那么这不是您想要的。
这就是你想要的,如果你想要Linq:
var board = Enumerable.Range(0, 3)
.Select(n => Enumerable.Repeat('.', 3).ToArray())
.ToArray();
每次 Select()
执行代码,因此您执行的代码每次都可以创建一个新数组。 Repeat()
只是不断返回你给它的任何价值。