Have the ilists gone at a cost?

Passing Parameters of type value for functions in C # by value, unless you use the ref or out keyword for a parameter. But does this also apply to Reference Types ?

In particular, I have a function that accepts IList<Foo> . Will the list passed to my function be a copy of the list with a copy of its contained objects? Or are the changes to the list also applicable to the caller? If so - is there a trick, can I go about transferring 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
pass-by-reference c # parameters
source share
6 answers

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. That is, the link itself is copied, but since it still points to the same instance, you can still modify the instance using this link. That is, the instance is not copied. There is a link.

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

+16
source share

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

Here's how I like to think about it.

A variable is a storage location.

A variable can store something of a certain type.

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

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

A value of a value type variable is an object of this type.

A formal parameter is a kind of variable.

There are three types of formal parameters: parameter values, ref parameters, and out parameters.

When you use a variable as an argument that matches a value parameter, the value of the variable is copied to the repository associated with the formal parameter. If the variable is of type value, then a copy of the value is created. If the variable has a reference type, then a copy of the link is made, and now two variables refer to the same object. In either case, a copy of the value of the variable is created.

When you use a variable as an argument that matches the out or ref parameter, that parameter becomes an alias for the variable . When you speak:

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

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

I find it much easier to understand than to think about how the alias is implemented - passing the managed address of a variable to a formal parameter.

It is clear?

+10
source share

The list is passed by reference, so if you change the list in SomeFunction, you also change the list for the caller.

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

 var newList = new List<Foo>(oldList); 
+3
source share

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 the clone, it will not change the list but modifications of the elements themselves will be taken into account in both lists.

+2
source share

When you pass a reference type by value (without keywords or links), you can change this type of link inside this method, and all changes will reflect the code of the callers.

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

 list.AsReadOnly(); 
+1
source share

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

If you pass the link

byref, you directly pass the link (pointer).

byval, you are passing a copy of the link (pointer).

The link does not apply to the instance. The link is similar to the index.

To transfer a copy of an instance of type referencetype, you must first make a copy and pass a reference to the copy. This way you will not modify the original instance.

0
source share

All Articles