简体   繁体   中英

Class and List<> Reference Type in c#

I have some doubts in below code regarding CASE 1 and CASE 2,

In CASE-1, we are assigning obj1=null , but in obj2 the copied value is still present as i =10.
In CASE-2, we do something in List , but the value changed in one list is affecting the value in another List .

What is the logic behind this as both are reference types.

CASE- 1

Class A    
{
public int i;
}

A obj1 = new A();
obj1.i =10;

A obj2 = obj1;
obj1 = null;

CASE- 2

List<int> test1 = new List<int>();
test1.Add(101);

List<int> test2 = test1;
test1.Add(201);

the logic is simple in both:

both A obj2 and List<int> test2 are reference to the same type as A obj1 and List<int> test1

whhich means that when you perform:

Class A    
{
public int i;
}

A obj1 = new A();
obj1.i =10;

A obj2 = obj1;
obj1 = null;

The value of obj2 will be assigned with the value of obj1 but is a object of it's own, it did not become obj1 but rather, just referenced him. obj2 became a new object of type A with the values assigned in obj1 .

When you assign obj1=null then obj2 will not be affected as it's value is already assigned.

however if you change it to:

obj1 = null;
A obj2 = obj1;

then obj2 will be null, as obj2 is now referencing an empty object.

the same applied in case 2:

List<int> test2 is referencing List<int> test1 and will be assigned it's value. as a result this piece of code:

List<int> test1 = new List<int>();
test1.Add(101);

List<int> test2 = test1;
test1.Add(201);

will produce the following items in test2:

101
201

you can read further into reference types in this article at Microsoft docs. It is pretty extended and covers almost everything.

  1. When you use new keyword at that time some memory is going to allocate and depending on type reference type and value type it get allocation in Heap or may be Stack. ( It is possible that value type may assigned to heap and it entirely depends on CLR)

  2. Difference between reference type and value type is that reference type hold reference of ( Address of) particular object created in heap. In value type , variable it self hold value.

  3. Now in your case 1 A a= new A(); // At this time memory allocated and that allocated memory location address is being assigned to variable a.

    A a1 = a; // At this point new variable a1 is created and that point to same address location in heap as variable a.

    a = null; // At this point variable a is set to null means it links with actual object allocated is heap get removed.

    but a1 still hold the reference so it can access value

  4. In case 2 ( This is also case of reference type) // Your variable test1 and test2 are different but holding same location of address from heap.

    // so if you change any item it get affected both variable as both point to same location.

    // Now if you do test1 = null then also test2 to do same thing but you can not access by test1 as it is null now.

CASE-1

obj1 = null;

reference to the object from obj1 has been removed. The object still exists thanks to obj2 .

CASE-2

Instead

test1 = null;

the method on List<int> is performed:

test1.Add(201);

Both test1 and test2 still point to the same List<int> , so changes in the list are visible.

I think Barr J's answer is a good one, and I'm not sure whether you'll find mine more or less helpful, but this stuff can be confusing enough that I think it's worthwhile to try explaining what's going on in a slightly different way.

A obj1 = new A();  // 1.1
obj1.i = 10;       // 1.2

A obj2 = obj1;     // 1.3
obj1 = null;       // 1.4

On line 1.1, the new operator creates an instance of a reference type A , and the = operator stores a reference to that instance in a variable called obj1 . In order to understand what's going on with your code it's important to distinguish between the reference (the value stored in obj1 ) and the referent (the object to which that value refers, which is stored elsewhere).

On line 1.2, the . operator serves to dereference the reference stored in obj1 —in other words, to access its referent, the instance of A that you created on line 1.1. This allows you to access the field i of that instance and assign it a value of 10.

Line 1.3 copies the reference stored in obj1 into a second variable called obj2 . You now have two references with the same referent. This means that obj2.i is also equal to 10, because the expressions obj1.i and obj2.i refer to exactly the same value.

Line 1.4 stores the null-reference into obj1 . The crucial difference between lines 1.2 and 1.4 is that there is no dereferencing occurring on line 1.4, so you're not affecting the referent in any way. All you're doing is replacing a reference to an object with a reference to nothing.

Now consider the code from your second example:

List<int> test1 = new List<int>();  // 2.1
test1.Add(101);                     // 2.2

List<int> test2 = test1;            // 2.3
test1.Add(201);                     // 2.4

Lines 2.1–2.3 are analogous to their counterparts in the first example: they construct an instance of List<int> and two references to that instance, which are stored in two variables of type List<T> called test1 and test2 . But line 2.4 is different: whereas line 1.4 replaced one reference with another, line 2.4 uses the . operator again to access the referent of test1 and update its contents.

You'll see the value 201 in the list regardless of whether you access it by way of the reference stored in test1 or the reference stored in test2 because both references have the same referent; in other words, you have only created a single list.

obj1 and test1 both are variables of reference type, just like pointers . They store references to their data (objects). obj1 and obj2 reference the same object but they are different variables. So that you assign null to obj1 doesn't change the data (object). test1 and test2 are different variables too, but test1.Add and test2.Add call the same method of the same object that they both reference.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM