On the effect of different types of variables stored in dictionaries

Recently, I am writing a gadget that uses a custom class and needs to instantiate multiple instances of the class.

Because different instances need to be fetched according to requirements, it is decided to put them in a dictionary for fetching.

In addition, the instantiation content may be changed later, so it is prepared to encapsulate the instantiated code into a separate subprogram for change.

 

So write the following code:

 1 namespace Example
 2 {
 3     public partial class MainWindow : Window
 4     {
 5         //Because it will be referenced in other places, it is placed in the outermost definition
 6         public static MyClass staff1; 
 7         public static MyClass staff2;
 8         public static Dictionary<string, MyClass> staffDic = new Dictionary<string, MyClass>()
 9         {
10             {"aaa",staff1},
11             {"bbb",staff2}
12         };
13 
14         private void Window_Loaded(object sender, RoutedEventArgs e)
15         {
16             InitializationStaff();
17             System.Console.WriteLine(staffDic["aaa"]);
18         }
19 
20         private void InitializationStaff() //Add instance to variable
21         {
22             staff1=new MyClass(){a=1,b=2,c=3};
23             staff2=new MyClass(){a=3,b=2,a=1};
24         }
25     }
26 
27     Class MyClass 
28     {
29         public int a;
30         public int b;
31         public int c;
32     }
33 }

It was found that an error was reported in the output, indicating that the corresponding content of the item in the dictionary is Null.

If you want to modify the code, instantiate it outside first:

namespace Example
{
    public partial class MainWindow : Window
    {
        //Because it will be referenced in other places, it is placed in the outermost definition
        //Instantiate when variables are defined
        public static MyClass staff1 = new MyClass(); 
        public static MyClass staff2 = new MyClass();
        public static Dictionary<string, MyClass> staffDic = new Dictionary<string, MyClass>()
        {
            {"aaa",staff1},
            {"bbb",staff2}
        };

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            InitializationStaff();
            System.Console.WriteLine(staffDic["aaa"]);
        }

        private void InitializationStaff() //Modify the variable
        {
            staff1.a = 1;
            staff1.b = 2;
            staff1.c = 3;

            staff2.a = 3;
            staff2.b = 2;
            staff2.a = 1;
        }
    }

    Class MyClass 
    {
        public int a;
        public int b;
        public int c;
    }
}

At this point, the output is normal.

So what happened behind this?

 

After consulting friends, I learned that in C, when adding the value corresponding to the key to the dictionary, the effect is actually to copy the target content to the dictionary, not to reference.

People who know about variables and memory should know that when we write the following line of code:

int a = 123;

What happens at this time is that the system first finds A piece of memory space, stores the value 123 in it, and records the address A of the memory space.

In variable a, the actual storage is address a.

 

When we add variables to the dictionary:

Dictionary<string, int> Dic = new Dictionary<string, int>() { { "number1", a } };

The dictionary first finds the variable a and gets the address a where the data is stored.

Then copy the contents of address A and paste them into another memory space opened by the dictionary. The address of this memory space is address B.

At this point, no matter how we assign the variable a, a in the dictionary will not change.

Because when assigning a value to variable a, the data in memory space with address a is actually modified, while a in dictionary is stored in memory space with address B.

 

However, according to this conclusion, the second method I used at the beginning of this article should be to modify the data of the members of the class externally, and the contents of the dictionary will not change?

Then why does the content of the dictionary change when it is modified externally?

 

When we write the following code:

 1 namespace Example
 2 {
 3     public partial class MainWindow : Window
 4     {
 5         private void Window_Loaded(object sender, RoutedEventArgs e)
 6         {
 7             public static MyClass staff = new MyClass(); 
 8         }
 9     }
10 
11     Class MyClass 
12     {
13         public int a;
14         public int b;
15         public int c;
16     }
17 }

In the variable staff, an address a is stored, and a type such as MyClass is stored in address a, that is, three variables a, b and c.

In fact, three variables a, b and c store address a, address b and address c respectively.

These three addresses point to the memory space where the data is stored.

 

When we add staff to the dictionary, the dictionary reads address A, and copies the contents stored at address A to the newly opened memory space at address B.

When copying, the addresses of a, B and c variables are copied to address B.

 

At this time, the external variable staff and the dictionary staff point to the same three memory spaces.

When the content is modified by the external variable staff, because the staff in the dictionary actually accesses the same address, the content in the dictionary will change accordingly.

 

In this way, it may be a bit messy. It should be clear to use the diagram to represent it.

 

All of the above are my understanding. If there is any omission, please give me more advice.

Tags: C#

Posted on Thu, 25 Jun 2020 01:53:08 -0400 by jimmyt1988