C# 用于引用类型数组的Buffer.BlockCopy的替代方案
对于引用类型的数组,是否有“缓冲区.BlockCopy”的安全替代方案 编辑:C# 用于引用类型数组的Buffer.BlockCopy的替代方案,c#,.net,arrays,C#,.net,Arrays,对于引用类型的数组,是否有“缓冲区.BlockCopy”的安全替代方案 编辑: 我的目的是在不同级别的数组之间移动数据,例如从Object[]移动到Object[,],而无需遍历数组 缓冲区。BlockCopy仅适用于基本类型 数组。复制可用于相同列组的数组 您可以使用或仅使用for循环。Buffer.BlockCopy的底层机制与这些方法之间的性能差异可以忽略不计,除了以每秒30帧的速度传输的运动图像数据。不要过早地进行优化。它们由GC跟踪。对象未固定 我相信这个拷贝可以在C++/CLI(或者
for
循环。Buffer.BlockCopy
的底层机制与这些方法之间的性能差异可以忽略不计,除了以每秒30帧的速度传输的运动图像数据。不要过早地进行优化。它们由GC跟踪。对象未固定
我相信这个拷贝可以在C++/CLI(或者,如果您想使用反射发射,可以在IL中)中安全地完成
您需要定义如下函数:
void Copy(int itemCount, ref object firstItemArray0, ref object firstItemArray1);
object[] array0 = new object[11 * 12];
object[,] array1 = new object[11, 12];
Copy(11 * 12, ref array[0], ref array1[0]);
void Copy(
int itemCount,
interior_ptr<object^> firstItemArray0,
interior_ptr<object^> firstItemArray1) {
for (int i = 0; i < itemCount; i++) {
firstItemArray1[i] = firstItemArray0[i];
}
}
这样称呼它:
void Copy(int itemCount, ref object firstItemArray0, ref object firstItemArray1);
object[] array0 = new object[11 * 12];
object[,] array1 = new object[11, 12];
Copy(11 * 12, ref array[0], ref array1[0]);
void Copy(
int itemCount,
interior_ptr<object^> firstItemArray0,
interior_ptr<object^> firstItemArray1) {
for (int i = 0; i < itemCount; i++) {
firstItemArray1[i] = firstItemArray0[i];
}
}
此调用将托管指针提交到Copy
Copy
现在有一个托管指针,指向要在其中复制的数组的第一个元素
Copy
不能用C#表示,因为不能对C#中的托管指针执行指针算术。事实上,ref
看起来根本不像指针
Copy
的C++/CLI实现如下所示:
void Copy(int itemCount, ref object firstItemArray0, ref object firstItemArray1);
object[] array0 = new object[11 * 12];
object[,] array1 = new object[11, 12];
Copy(11 * 12, ref array[0], ref array1[0]);
void Copy(
int itemCount,
interior_ptr<object^> firstItemArray0,
interior_ptr<object^> firstItemArray1) {
for (int i = 0; i < itemCount; i++) {
firstItemArray1[i] = firstItemArray0[i];
}
}
无效副本(
int itemCount,
内部ptr firstItemArray0,
内部(ptr第一项阵列1){
对于(int i=0;i
只是一张草图。如果您不喜欢C++/CLI项目,请反汇编IL并使用反射发射生成它
只是想说明一点:这是GC友好的、无法验证但安全的。我看不出有什么理由不能投入生产
现在,为什么不为循环使用
?多维数组在当前的JIT中速度较慢。它们包含边界检查和索引计算。这就避免了所有这些。您想要什么样的安全性?可以在生产中使用的东西…您希望在执行复制时不修改数组吗?实际上,我需要在不同列组的数组之间复制相同的数据。Dmitry:Buffer.BlockCopy仅适用于结构(值类型)。确定。但是,BlockCopy能够在不同列组的阵列之间移动数据(不幸的是,我需要此选项),因为不同列组的阵列被视为不同的类型,所以在CLR中无法安全地执行此操作。Buffer.BlockCopy并不是真正安全的(它将数据视为字节,而不是类型),因此可以绕过这个问题。您必须使用for循环。谢谢,这是usr!您的方法是否优于下一个示例(在数组之间复制字节)@user876301 pastebin中的此方法不适用于托管引用。GC可以随时重新定位对象并重写指向它们的指针。使用托管指针,就像在我的回答中一样,可以确保GC可以更新这些指针。