C#: 将数组分配给另一个数组:复制还是指针交换?

12

很抱歉提出这个问题,我已经谷歌了一下,但似乎出现的都是克隆或复制方法的参考,而不是 C# 中实际回答我的问题的答案。

我有两个字节数组,并且它们被两个线程访问。

private byte[] buffer1 = new byte[size];
private byte[] buffer2 = new byte[size];

我的目标是在Thread1中向buffer1中写入内容,获取互斥对象,交换指针并重复此过程。 Thread2将获取互斥对象并始终读取buffer2

目标是使Thread2运行速度快,并且不受Thread1中进行的复制的影响。

我非常不清楚当我执行以下操作时会发生什么:

byte[] temp = buffer1;
buffer1 = buffer2;
buffer2 = temp;

指针是否被切换或者buffer2的内容被复制到buffer1?这应该是一个简单的问题,但我似乎找不到答案。 Thread1正在执行Marshal.Copy(),我不希望这个调用影响到Thread2


3
你是否尝试过做一些测试来观察会发生什么? :) - David Sherret
2
在您的代码片段中,“buffer1”和“buffer2”最终引用同一个数组。我猜您想要在经典交换中使用“temp”。 - Matt Burland
2
我误复制了那个。请立即进行编辑,谢谢 :) - Jary316
请查看Buffer.BlockCopy() - John Alexiou
2个回答

25

赋值操作总是将一个表达式的值复制到一个变量中(或调用属性/索引器的setter)。

针对您的情况,使用以下代码:

buffer1 = buffer2;

...buffer2的值只是一个指向字节数组的引用。因此,在进行此赋值后(假设没有其他赋值),通过一个变量对字节数组所做的更改将通过另一个变量可见。

这不仅适用于数组类型-这就是.NET中所有引用类型的工作方式:

StringBuilder x = new StringBuilder();
StringBuilder y = x;
x.Append("Foo");
Console.WriteLine(y); // Foo

只需要理解数组始终是引用类型即可。


太棒了,非常感谢!这真的是我想知道的,谢谢! - Jary316

10
Array类是引用类型,因此没有复制,只有引用分配。使用Array.CopyTo方法将一个数组的内容复制到另一个数组中。
这种行为与C++不同,在.NET中,您无法覆盖它,并且没有办法在赋值发生时复制某个集合的内容。
另一件事,您想要进行的引用分配是一个原子操作,因此您可以考虑在代码中使用无锁算法来处理此部分代码。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接