这是引用的调用吗



我有一个ArrayList:

ArrayList ReceivedPackets = new ArrayList();

我还有另一个ArrayList:

ArrayList returnList = ReceivedPackets;

当我运行此代码时,returnList为什么会丢失它的值?

ArrayList ReceivedPackets = new ArrayList();  // ReceivedPackets is empty
ReceivedPackets.Add(1);                       // Now it has an Integer
ArrayList returnList = ReceivedPackets;       // Call-by-Reference (I thought), returnList now has an Integer
ReceivedPackets.clear();                      // returnList is empty now. Why?

执行此操作时:

ArrayList returnList = ReceivedPackets;

您正在创建一个名为returnList的新变量,但该变量指向内存中与ReceivedPackets相同的对象。仍然只有一个实际的ArrayList,它只有两个指向它的变量。所以对其中一个的更改反映在这两个变量中。

我怎么能不让returnList失去它的价值?

创建一个新对象。最简单的情况是:

ArrayList returnList = new ArrayList();

如果您还希望该对象包含ReceivedPackets中的所有值,幸运的是,ArrayList有一个构造函数重载,它可以做到这一点:

ArrayList returnList = new ArrayList(ReceivedPackets);

现在您有两个对象,它们应该包含相同数据的副本。对其中一个的更改不会反映在另一个中。


在没有构造函数的情况下,ArrayList也有一些CopyTo()方法,可以用来将元素从一个复制到另一个。如果做不到这一点,您还可以手动在源ArrayList上循环,并将元素复制到目标ArrayList

如果ArrayList本身包含引用对象,这可能会非常令人困惑。因为它们也可能有多个指向同一内存对象的"指针"。

例如,如果创建一个Widget对象并将其添加到两个ArrayList对象中,则对ArrayList对象所做的任何修改(添加/删除元素)都将是独立的,但对Widget对象所作的任何修改都将反映在两个ArrayList s中。

关键是ArrayList本身是一个对象,与它所包含的对象无关。

因此,根据你所做事情的全部背景,你的里程数可能会有所不同。

ArrayList是一个引用类型,这意味着如果您简单地将某个变量分配给它的一个实例,两个对象将指向内存中的同一位置。

如果要创建深度复制,请创建一个新对象。

static void Main() {
    ArrayList a = new ArrayList() {1,2,3};
    var b = a;
    var c = new ArrayList(a);
    a.Clear();
    Console.WriteLine(a.Count); // 0
    Console.WriteLine(b.Count); // 0
    Console.WriteLine(c.Count); // 3
}

相关内容

  • 没有找到相关文章

最新更新