6

In the following scenario, would "Pool" be returned by value or by reference?

private static List<Item> Pool;

public static List<Item> GetPool()
{
    return Pool;
}

I want to achieve the ability to loop through the list at the time it was requested (so that another thread could add/remove items from the list but the calling thread's list stays the same so that the foreach loop does not cause an exception). If it was returned by value then it would be its own list whereas if it was a reference, I'd still be in danger of the list being modified. Please correct me if anything is wrong, this is just my understanding

Solo116
  • 129
  • 1
  • 6
  • 3
    Why don't you set up a test scenario and examine it in a debugger to find out? With the 5 lines of code you posted, I think you're already 50% done with a viable test-setup. – abelenky Apr 07 '16 at 18:35
  • 1
    Why don't you look at BlockingCollection or ConcurrentBag date types in .net 4.0+ - it should be suitable for your task – Ivan Yuriev Apr 07 '16 at 18:41

3 Answers3

9

All methods always return a value. They can never return a reference.

If it was returned by value then it would be its own list whereas if it was a reference, I'd still be in danger of the list being modified.

That is false. The value being returned is not the list, but a reference to the list object, because List is a reference type, so any code using the value returned from this method and any code accessing that field directly are using different copies of references to the same list.

Servy
  • 202,030
  • 26
  • 332
  • 449
5

C# always returns by value*. However, in C# most types are reference types, which means any variable of that type is a reference; and it is that reference which is returned by value.

(*) That is, until ref returns make it in (C# 7?).

Asik
  • 21,506
  • 6
  • 72
  • 131
  • C# returns reference types by reference. – Bauss Apr 07 '16 at 18:40
  • 1
    @Bauss No, it does not. It returns *all* types by value. – Servy Apr 07 '16 at 18:40
  • In his example the value returned by the function will be a reference to the list declared. That you can change the reference is a completely different talk and has to do with C#'s lack of immutability. – Bauss Apr 07 '16 at 18:41
  • 1
    @Bauss Yes, the **value** returned, not the **reference** returned, because the method (like every single method always does in C#) returns a *value*. – Servy Apr 07 '16 at 18:42
  • Class values are always references. – Bauss Apr 07 '16 at 18:42
  • 1
    @Bauss Yes, and those references are passed by value when returned from a method. – Servy Apr 07 '16 at 18:43
4

The Pool is a variable of type List<Item>. Hence it holds a reference to an object of type List<Item> or it is null. That being said, when you read this value (actually that GetPool does), you get a reference to this object (or null).

Let's make a bit more clear what is the main difference between a value type and a reference type. int is a value type. Let's consider the following piece of code.

int a = 4;
int b = a;
a = 5;

What are the values of a and b after the above declarations and assignments have been done?

The value of a would be 5 and the value of b would be 4. Why? The first statement copies the literal value of 4 to the a. The second statement copies the value of a to b. Hence b's value are 4. Please, pay attention here, the a's four is different from b's four. (It's like you have two copies of the same book. The one copy belongs to the a and the other to b). After the third statement, the value of a would be 5.

On the other hand a class is a reference type. Let's declare the following class:

public Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

Let's consider now that we have the following piece of code.

var personA = new Person { FirstName = "Bob", LastName = "Barney" };
var personB = personA;
personA.FirstName = "Jack";

What would be the values of personA.FirstName and personB.FirstName?

They would be exactly the same, Jack. Why?

Because in this line

var personB = personA;

we have a copy by reference (since a class is a reference type). What does it mean in terms of the book's paradigm we mentioned above ? Now it is like we have thrown the physical copies of a book and we have shared a URL, in which we can read the book. Since, we both have the same reference, when something changes in the page 30, it would be visible from both of us.

Chris
  • 38
  • 4
Christos
  • 53,228
  • 8
  • 76
  • 108