dnvThai
dnvThai

Reputation: 123

Two array's element reference to an object

I have the following code:

struct NewType
{
    public int val;
}

static void Main(string[] args)
{
    NewType i = new NewType();
    List<NewType> IList = new List<NewType>();

    i.val = 1;
    IList.Add(i);

    i.val = 2;
    IList.Add(i);
}

After that, If I print each of element in IList list, the result will be 12 It's opposite than what I thought 22

Because: enter image description here

Someone tells me why the result was 12?

Upvotes: 1

Views: 58

Answers (5)

Adil
Adil

Reputation: 148130

Because NewType is a struct and struct is a value type but not reference type like class. If you have class instead of struct you will get 22, this post will help you to understand.

Upvotes: 1

jeromerg
jeromerg

Reputation: 3135

IList.Add(i) performs implicitely a shallow copy of i because NewType is a value type (a struct). While performing the shallow copy, it copies also the field NewType.val by value. So IList contains two different NewType values, which themselves contain a different val integer.

If you change NewType from struct to class, then you will get what you are expecting.

Upvotes: 0

Christos
Christos

Reputation: 53958

The type NewType is a value type, not a reference type. That means that IList, whose type is List<NewType>, holds copies of the values not references to them. That being said, your picture is not correct.

After that, If I print each of element in IList list, the result will be 12 It's opposite than what I thought 22

This is the expected.

Here

i.val = 1;
IList.Add(i);

You add a copy of the value of i in the IList. This copy's the value of val is 1.

Then

i.val = 2;
IList.Add(i);

You change the value of the val by copying to it the value of 2. After this you add a copy of i to the IList. This copy's value of val is 2.

In order you notice that you have described in your question, the type NewType should be a reference type. If you change the definition of NewType to the following one:

class NewType
{
    public int val;
}  

you will notice thta you have described.

Upvotes: 2

Adriaan Stander
Adriaan Stander

Reputation: 166406

This is because NewType is a struct, which is added to the list as a value type (a copy of the object is added to the list, not the reference to the original object).

If you changed it from struct to class then it would be as you expected. The class is passed by reference.

Have a look at Classes and Structs (C# Programming Guide)

A struct is a value type. When a struct is created, the variable to which the struct is assigned holds the struct's actual data. When the struct is assigned to a new variable, it is copied. The new variable and the original variable therefore contain two separate copies of the same data. Changes made to one copy do not affect the other copy.

Upvotes: 2

Benjy Kessler
Benjy Kessler

Reputation: 7636

Basic data types work different than abstract data types. ints are not references and therefore are actually copied unlike non-basic data types.

Upvotes: 0

Related Questions