Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/325.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 用于引用类型数组的Buffer.BlockCopy的替代方案_C#_.net_Arrays - Fatal编程技术网

C# 用于引用类型数组的Buffer.BlockCopy的替代方案

C# 用于引用类型数组的Buffer.BlockCopy的替代方案,c#,.net,arrays,C#,.net,Arrays,对于引用类型的数组,是否有“缓冲区.BlockCopy”的安全替代方案 编辑: 我的目的是在不同级别的数组之间移动数据,例如从Object[]移动到Object[,],而无需遍历数组 缓冲区。BlockCopy仅适用于基本类型 数组。复制可用于相同列组的数组 您可以使用或仅使用for循环。Buffer.BlockCopy的底层机制与这些方法之间的性能差异可以忽略不计,除了以每秒30帧的速度传输的运动图像数据。不要过早地进行优化。它们由GC跟踪。对象未固定 我相信这个拷贝可以在C++/CLI(或者

对于引用类型的数组,是否有“缓冲区.BlockCopy”的安全替代方案

编辑

  • 我的目的是在不同级别的数组之间移动数据,例如从Object[]移动到Object[,],而无需遍历数组

  • 缓冲区。BlockCopy仅适用于基本类型

  • 数组。复制可用于相同列组的数组

  • 您可以使用或仅使用
    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可以更新这些指针。