[英]C# Copy 2D matrix issue
我有A班:
public class A {
private Point[,] matrix = null;
private int r, c;
public Point[,] Matrix
{
get
{
if (this.matrix == null || this.matrix.Length == 0)
{
// Matrix is null or it has no elements on it.
return null;
}
else
{
return this.matrix;
}
}
}
public A(int r, int c)
{
this.r = r;
this.c = c;
this.matrix = new Point[r, c];
}
public void InitializeMatrix
{
for (int i = 0; i < r; i++)
{
for (int j = 0; j < c; j++)
{
this.matrix[i, j] = new Point(i, j);
}
}
}
public void CopyMatrix(out Point[,] copyMatrix)
{
if (this.Matrix == null)
{
throw new ArgumentException("Matrix is null.", "Matrix");
}
Point[,] m = new Point[r, c];
for (int i = 0; i < r; i++)
{
for (int j = 0; j < c; j++)
{
m[i, j] = this.Matrix[i, j];
}
}
copyMatrix = m;
}
}
点是一类:
public class Point
{
public int x, y;
public Point (int x, int y)
{
this.x = x;
this.y = y;
}
}
因此,从另一个类,我们说B:
public class B
{
private A instanceA;
public B (A a)
{
// imagine a valid not null instance of class A is passed.
this.instanceA = a;
}
private void SomeMethod()
{
Point[,] m;
this.instanceA.CopyMatrix(out m);
m[2, 4].x = 9; <--- here is the problem
Console.WriteLine(String.Format("{0}",this.instanceA.Matrix[2, 4].x));
}
}
问题是:
在类B的SomeMethod方法中,当我更新本地矩阵Point [,] m时,也更新了类A中的矩阵'matrix'。
Console.WriteLine(this.instanceA.Matrix[2, 4]);
它也输出9。 为什么? 其内容也已更改...
这里的问题是您没有正确理解“引用”类型和“原始”类型之间的区别。
对于基本类型(数字,例如int
或long
); 变量本身分配在堆栈上,并包含实际数值本身。 如果我做
int foo = 1;
int bar;
bar = foo;
这将在堆栈上为名为foo
的变量分配空间,为其分配值1
,在堆栈上为bar
分配更多空间,然后将数字1
复制到bar
。 这两个变量保持彼此独立,所以如果我现在这样做
bar = 4
foo
保持不变。
对于一个对象,正在发生一些不同的事情。 采取以下措施:
class MyObject {
public int x;
}
// Inside some method somewhere
MyObject foo = new MyObject();
MyObject bar;
foo = bar;
在这种情况下,正在为MyObject
实例在堆上分配内存。 然后,将一个名为foo
的引用变量分配到堆栈上,并使用刚刚创建的MyObject
的内存地址进行初始化。
这是关键点; 在这种情况下, foo
不包含object ,只是对其的引用。 这意味着当在下一行分配新的引用类型bar
,现在为foo = bar
行分配了同一分配对象的内存地址 。
这意味着我们可以执行以下操作
foo.x = 1;
bar.x = 10;
由于foo和bar现在都指向相同的内存地址 ,如果我们将 foo.x
或bar.x
的值打印到控制台,则结果将为10。
那么,这与您的问题有什么关系? 简单; 您的矩阵是对Point
对象的引用数组,而不是Point
对象本身。 所以你的代码行
m[i, j] = this.Matrix[i, j];
只是将这些对相同Point
对象的引用复制到新矩阵中。 解决您的问题; 将上面的行更改为以下内容:
m[i, j] = new Point(this.Matrix[i, j].x, this.Matrix[i, j].y);
取而代之的是在堆上为全新的Point
对象分配内存,并使用旧对象中的值对其进行初始化。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.