Are ILists passed by value?

2020-02-09 16:21发布

Passing Value Type parameters to functions in c# is by value unless you use the ref or out keyword on the parameter. But does this also apply to Reference Types?

Specifically I have a function that takes an IList<Foo>. Will the list passed to my function be a copy of the list with copy of its contained objects? Or will modifications to the list also apply for the caller? If so - Is there a clever way I can go about passing a copy?

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

public void DoSomethingWithCopyOfTheList(IList<Foo> list)
{
    // Do something
}

6条回答
Deceive 欺骗
2楼-- · 2020-02-09 16:52

The list is passed by reference, so if you modify the list in SomeFunction, you modify the list for the caller as well.

You can create a copy of a list by creating a new one:

var newList = new List<Foo>(oldList);
查看更多
做个烂人
3楼-- · 2020-02-09 17:03

When you pass reference type by value (without ref or out keywords) you may modify this reference type inside this method and all changes will reflect to callers code.

To solve your problem you may explicitly create a copy and pass this copy to your function, or you may use:

list.AsReadOnly();
查看更多
别忘想泡老子
4楼-- · 2020-02-09 17:04

When passing reference types, you pass the reference. This is an important concept.

If you pass a reference

byref, you pass the reference (pointer) directly.

byval, you pass a copy of the reference (pointer).

A reference is not the instance referenced. A reference is analagous to a pointer.

To pass a copy of the instance of a referencetype, you first must make a copy yourself and pass a reference to the copy. As such then you will not be modifying the original instance.

查看更多
狗以群分
5楼-- · 2020-02-09 17:09

All parameters are passed by value unless you explicitly use ref or out. However, when you pass an instance of a reference type, you pass the reference by value. I.e. the reference itself is copied, but since it is still pointing to the same instance, you can still modify the instance through this reference. I.e. the instance is not copied. The reference is.

If you want to make a copy of the list itself, List<T> has a handy constructor, that takes an IEnumerable<T>.

查看更多
我想做一个坏孩纸
6楼-- · 2020-02-09 17:12

You're not alone; this confuses a lot of people.

Here's how I like to think of it.

A variable is a storage location.

A variable can store something of a particular type.

There are two kinds of types: value types and reference types.

The value of a variable of reference type is a reference to an object of that type.

The value of a variable of value type is an object of that type.

A formal parameter is a kind of variable.

There are three kinds of formal parameters: value parameters, ref parameters, and out parameters.

When you use a variable as an argument corresponding to a value parameter, the value of the variable is copied into the storage associated with the formal parameter. If the variable is of value type, then a copy of the value is made. If the variable is of reference type, then a copy of the reference is made, and the two variables now refer to the same object. Either way, a copy of the value of the variable is made.

When you use a variable as an argument corresponding to an out or ref parameter the parameter becomes an alias for the variable. When you say:

void M(ref int x) { ...}
...
int y = 123;
M(ref y);

what you are saying is "x and y now are the same variable". They both refer to the same storage location.

I find that much easier to comprehend than thinking about how the alias is actually implemented -- by passing the managed address of the variable to the formal parameter.

Is that clear?

查看更多
老娘就宠你
7楼-- · 2020-02-09 17:15

your list is passed by reference. If you want to pass a copy of the list you can do:

IList<Foo> clone = new List<Foo>(list);

if you add/remove elements in clone it won't modify list but the modifications of the elements themselves will be taken into account in both lists.

查看更多
登录 后发表回答