代码之家  ›  专栏  ›  技术社区  ›  James Van Huis

通过引用传递的数组的修改

  •  3
  • James Van Huis  · 技术社区  · 16 年前

    我最近遇到了一些第三方C#代码,它执行以下操作:

    public int RecvByteDataFromPrinter(ref byte[] byteData)
    {
        byte[] recvdata = new byte[1024];
    
        ///...fills recvdata array...       
    
        byteData = recvdata;
        return SUCCESS;
    }
    

    这条线是什么?” byteData = recvdata “在这种情况下,你真的这么做了吗?

    目标似乎是让byteData包含recvdata数组的内容。然而,我的印象是,你需要做一个 Array.Copy(...) 为了实现这一点。

    这实际上是在修改byteData引用以指向新分配的数组吗?如果是这样,这个阵列能保证存在吗?

    4 回复  |  直到 12 年前
        1
  •  7
  •   Paul Kapustin    16 年前

    是的,因为ref,它确实修改了传递的引用。 留下来?你是说,没有被摧毁?是的,由于新的引用,它不会被GC。如果没有更多的引用,则旧数组(传递的)可能会在分配后被GC化。..

    阵列。Copy实际上会复制元素,因此您不需要“ref”,但这将更耗时

        2
  •  2
  •   Dan C.    16 年前

    您猜对了,赋值操作正在修改byteData数组引用,以指向新分配的数组(因为使用了'ref'关键字)。函数的调用者将“看到”recvData数组的内容(无论其中填写了什么)。

    是的,只要还有一个对它的引用,数组就会一直存在(在这种情况下,无论你传递给这个函数的是什么数组)。

        3
  •  1
  •   Zach    16 年前

    该代码将把recvdata数组引用分配给byteData数组引用。 .NET将在其垃圾收集逻辑的掩护下跟踪分配,这样,只要byteData在作用域内,最初分配给recvdata的字节数组就不会在您的下面消失。

        4
  •  0
  •   ctacke    16 年前

    byteData引用现在将指向recvdata数组,为其提供根。它将“一直存在”,直到它的所有根都消失了(即被调用的对象摆脱了传入的byteData对象),它成为一个集合候选。一旦方法返回,传递的原始数组对象就是收集的候选对象。