0

我有一个数组列表:

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?
4

2 回答 2

2

当你这样做时:

ArrayList returnList = ReceivedPackets;

您正在创建一个名为的新变量returnList,但此变量指向与 相同的内存对象ReceivedPackets。仍然只有一个 actual ArrayList,它只有两个指向它的变量。因此,对其中一个所做的更改会同时反映在两者中。

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

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

ArrayList returnList = new ArrayList();

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

ArrayList returnList = new ArrayList(ReceivedPackets);

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


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

如果它本身包含引用对象,这可能会变得非常混乱。因为它们也可能有多个指向同一个内存对象的“指针”。ArrayList

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

关键是它ArrayList 本身是一个对象,独立于它所包含的对象。

因此,根据您正在做的事情的完整背景,您的里程可能会有所不同。

于 2016-05-10T14:59:35.380 回答
1

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
}
于 2016-05-10T15:03:24.497 回答