将对象作为构造函数参数传递似乎是通过引用而不是值传递

时间:2018-03-09 07:19:49

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

我有一个奇怪的问题,我在创建一个新对象,其中包含我通过我的函数使用的另一个对象(paramObj)的参数。因此,paramObj用在对象构造函数中,但在调用构造函数后最终会被更改。由于C#是按值传递的,我不确定为什么会这样。

我的代码:

void MyFunction(List<string> filesets)
{
    foreach(Fileset fs in filesets)
    {
        //At this point, fs.allFiles.Count is 30. The MyNewObject class
        //takes a Fileset as a parameters and eventually clears the 
        //Fileset.allFiles List, making the count 0.
        MyNewObject tmpObj = new MyNewObject(fs, null, "default");

        //At this point, fs.allFiles.Count is 0, but I expect it to be 30

    }
}

MyNewObject类只清除allFiles类中包含的Fileset列表。如果C#通过值传递,为什么会在构造函数之后显示?

2 个答案:

答案 0 :(得分:4)

你正确的是 .NET中的所有内容都按值传递。甚至引用 - 这就是fs 实际上 - 是按值传递的。因此,当您通过fs时,您的方法会有该参考的副本。但是,此引用引用完全相同的对象,对该引用进行任何更改,同时修改后备对象

因此,在您的构造函数中,您FileSet的{​​{1}} - 实例引用第二个引用fs

这或多或少导致结论,引用 有效传递对象。

没有简单的方法来规避这一点。这取决于你甚至在构造函数中修改该对象上的任何内容的原因。您可以尝试复制构造函数中fs引用的提供对象,例如通过在IClonable中实现FileSet或在该类或其他内容中提供复制构造函数。但是,根据FileSet及其成员的不同,您需要提供实例的副本。

有关如何制作对象的深层副本的详细信息,请参阅此处:Deep cloning objects

答案 1 :(得分:1)

通常,所有对象都通过引用作为参数传递给方法。另一方面,大多数原始数据类型(如整数,双精度,布尔值等)都是按值传递的。