Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将对象作为构造函数参数传递似乎是通过引用而不是值传递_C#_Pass By Reference_Pass By Value - Fatal编程技术网

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

C# 将对象作为构造函数参数传递似乎是通过引用而不是值传递,c#,pass-by-reference,pass-by-value,C#,Pass By Reference,Pass By Value,我遇到了一个奇怪的问题,我正在创建一个新对象,其中包含我通过函数使用的另一个对象(paramObj)的参数。因此,paramObj在对象构造函数中使用,但在调用构造函数后,它最终会被更改。由于C#是通过值传递的,我不确定为什么会发生这种情况 我的代码: void MyFunction(List<string> filesets) { foreach(Fileset fs in filesets) { //At this point, fs.allFil

我遇到了一个奇怪的问题,我正在创建一个新对象,其中包含我通过函数使用的另一个对象(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

    }
}
void MyFunction(列出文件集)
{
foreach(文件集中的文件集fs)
{
//此时,fs.allFiles.Count是30
//将文件集作为参数,并最终清除
//Fileset.allFiles列表,使计数为0。
MyNewObject tmpObj=newmynewobject(fs,null,“默认值”);
//此时,fs.allFiles.Count是0,但我希望是30
}
}

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

通常,所有对象都是通过引用作为参数传递给方法的。另一方面,大多数基本数据类型(如integer、double、Boolean等)都是通过值传递的。

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

你说得对,在.NET中的所有数据都是按值传递的。甚至引用(这就是
fs
的实际情况)都是按值传递的。因此,当您在方法周围传递
fs
时,将有该引用的副本。但是,此引用引用了完全相同的对象,对该引用进行任何更改,同时修改支持对象

因此,在构造函数中,您有一个
fs
引用的
文件集的第二次引用

这或多或少导致了一个结论,即对象是通过引用有效地传递的

没有简单的方法可以避免这种情况。这取决于为什么您甚至在构造函数中修改该对象上的任何内容。您可以尝试在构造函数中复制由
fs
引用的提供的对象,例如,在
FileSet
中实现
IClonable
,或者在该类中提供一个复制构造函数,等等。但是,根据
文件集的内容及其成员,您将需要所提供实例的一些深度副本


有关如何制作对象深度副本的进一步阅读,请参见此处:

你说得对,在.NET中的所有内容都是通过值传递的。甚至引用(这就是
fs
的实际情况)都是按值传递的。因此,当您在方法周围传递
fs
时,将有该引用的副本。但是,此引用引用了完全相同的对象,对该引用进行任何更改,同时修改支持对象

因此,在构造函数中,您有一个
fs
引用的
文件集的第二次引用

这或多或少导致了一个结论,即对象是通过引用有效地传递的

没有简单的方法可以避免这种情况。这取决于为什么您甚至在构造函数中修改该对象上的任何内容。您可以尝试在构造函数中复制由
fs
引用的提供的对象,例如,在
FileSet
中实现
IClonable
,或者在该类中提供一个复制构造函数,等等。但是,根据
文件集的内容及其成员,您将需要所提供实例的一些深度副本


要进一步了解如何制作对象的深度副本,请参见此处:

参考
fs
按值传递。从逻辑上讲,内容是通过引用传递的。你是说文件集对象的所有字段都是通过引用传递的吗?这与通过引用传递的整个对象不一样吗?这有什么关系吗?你看过那篇文章吗?如果要防止构造函数更改其接收的引用的对象,请尝试以下操作:
MyNewObject tmpObj=newmynewobject((Fileset)fs.Copy(),null,“default”)参考
fs
按值传递。从逻辑上讲,内容是通过引用传递的。你是说文件集对象的所有字段都是通过引用传递的吗?这与通过引用传递的整个对象不一样吗?这有什么关系吗?你看过那篇文章吗?如果要防止构造函数更改其接收的引用的对象,请尝试以下操作:
MyNewObject tmpObj=newmynewobject((Fileset)fs.Copy(),null,“default”)