IList是否通过了价值?

sti*_*k81 6 c# parameters pass-by-reference

除非在参数上使用ref或out关键字,否则将值类型参数传递给c#中的函数.但这也适用于参考类型吗?

具体来说,我有一个功能,需要一个IList<Foo>.传递给我的函数的列表是否是包含其包含对象的副本的列表的副本?或者对列表的修改是否也适用于呼叫者?如果是这样的话 - 我可以通过一种聪明的方式传递副本吗?

public void SomeFunction()
{
    IList<Foo> list = new List<Foo>();
    list.Add(new Foo()); 
    DoSomethingWithCopyOfTheList(list);
    ..
}

public void DoSomethingWithCopyOfTheList(IList<Foo> list)
{
    // Do something
}
Run Code Online (Sandbox Code Playgroud)

Bri*_*sen 16

除非您明确使用ref或,否则所有参数都按值传递out.但是,当您传递引用类型的实例时,您将按值传递引用.即引用本身被复制,但由于它仍然指向同一个实例,您仍然可以通过此引用修改实例.即实例未被复制.参考是.

如果你想复制一个列表本身,List<T>有一个方便的构造函数,需要一个IEnumerable<T>.

  • 此外,如果您更改函数体内的引用,则调用者将看不到此更改。我的+1。 (2认同)
  • @Aggelos:没错。这是按值传递的属性。 (2认同)

Eri*_*ert 10

你不是一个人; 这让很多人感到困惑.

这就是我想要的方式.

变量是存储位置.

变量可以存储特定类型的东西.

有两种类型:值类型和引用类型.

引用类型变量的值是对该类型对象的引用.

值类型变量的值是该类型的对象.

形式参数是一种变量.

有三种形式参数:值参数,参数参数和输出参数.

使用变量作为与value参数对应的参数时,变量的值将复制到与formal参数关联的存储中.如果变量是值类型,则创建该值的副本.如果变量属于引用类型,则会生成引用的副本,并且这两个变量现在引用同一对象.无论哪种方式,都会生成变量值的副本.

当您使用变量作为对应于out或ref参数的参数时,该参数将成为变量的别名.当你说:

void M(ref int x) { ...}
...
int y = 123;
M(ref y);
Run Code Online (Sandbox Code Playgroud)

你所说的是"x和y现在是同一个变量 ".它们都指向相同的存储位置.

我发现通过将变量的托管地址传递给形式参数,比考虑别名实际实现方式更容易理解.

明白了吗?


Mar*_*ann 5

该列表是通过引用传递的,因此如果您修改 SomeFunction 中的列表,您也会修改调用者的列表。

您可以通过创建新列表来创建列表的副本:

var newList = new List<Foo>(oldList);
Run Code Online (Sandbox Code Playgroud)