这是按引用进行的调用吗?

时间:2016-05-10 14:53:19

标签: c# pass-by-reference call-by-value

我有一个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?

2 个答案:

答案 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
}