我有一个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?
答案 0 :(得分:2)
执行此操作时:
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
本身是一个对象,与其包含的对象无关。
因此,根据您所做的全部情况,您的里程可能会有所不同。
答案 1 :(得分: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
}