C # Value types and reference types are understood in the English language

Source: Internet
Author: User

I have just used C # One months, may not understand, but also ask you to advise.
Read the article you need to understand the C language pointers.

Note the difference: for c\c++, any type can be used as a "reference type" for C # because there are pointers.


On the memory
void foo () {    int aaa = 0;//value type, AAA allocated on stack (SUB esp,xx)    int* paaa = new int[123];//reference type, PAAA allocated on heap, HeapAlloc (G Etprocessheap () ...)    Foo2 (&AAA); The "reference" value type aaa}-> function exits, AAA is destroyed from the stack, and paaa still exists in the process heap. void Foo2 (int* paaa) {    *paaa = 123;}

Box and unbox
To make a very simple analogy:
There are functions:
void foo (int* pa) {    beginthread (&NEW_THREAD...,PA);//Start new thread operation Pointer pa}void new_thread (int* pa) {    Sleep (1000); New thread sleep 1 seconds    if (*pa = = 123)//judge the content of the PA pointer is 123        Outputdebugstringa ("OK.");    }

There are also functions:
void Exec1 () {    int pa = 123;    Foo (&PA);}


You may see the problem, when we execute Foo pointing to the PA on the stack, because the EXEC1 function has exited, the value of the PA is reclaimed by the system, unpredictable, the line Cheng in a second after sleep to access the address on the stack can get the value is not 123, but if we allocate on the heap:
void Exec2 () {    int* pa = (int*) malloc (sizeof (int));    *PA = 123;    Foo (PA);}

Execute EXEC2, you can ensure that the PA is not recycled because there is no explicit free.

C # in the same way, box is the value type PA in exec1 to EXEC2 processing, and then after the processing The PA value is still destroyed on the stack after the EXEC1 exits, but the PA that executes Foo goes in is one. NET allocates a new pointer through a method like malloc, which allocates heap memory, and put the value PA on the original stack to memcpy in., and give this pointer to the Foo function, the "pointer" is the "reference type" after being boxed (box), when Foo refers to the PA, and give it to New_thread,new_thread after the PA is finished, no one ever uses this reference type PA,GC will take PA for free.

We can conclude that the stack type is automatically released by the system after the function body exits, and the heap type does not, remember ATL's ccomptr, and heap data relies on GC for garbage collection.
If you have an understanding of Windows COM and C + +, you can imagine this:
Atl::ccomptr = value type Auto-free. Why, because CComPtr is constructed in the function body (ADDREF), the function body exits the destructor (Release).
std::shared_ptr = reference type Auto-free. The class is new, shared_ptr is managed by reference count, and the reference count runs 0 when a function body exits to delete.

And then we can also conclude that the value type points to the actual data, and the reference type points to the data pointer
You can think of this in the back of your head, for example:
void foo () {    int aa = 123;//aa directly points to 123, the compiler indirectly accesses through the ESP pointer    int* PAA = (int*) malloc (sizeof (int));//paa points to a piece of memory on the heap    *PAA = 123;//compiler uses direct pointer access}

So, in C #, value types are also stack variables, and reference types are shared_ptr.

Conversely, a unboxing that refers to a value:
void foo () {    int* pa = new int[123];//reference type    pa[0] = 123;    int aa = *PA; AA is the value type on the stack, which memcpy,unbox the data from the heap}


so these 2 processes are a waste of time and a waste of memory.
As we can see from the above, value types are boxed to a reference type, the value type is changed after boxing, and the boxed reference type does not changeChange, or vice versa, such as:
void foo () {    int aa = 123;//value type    int* pa = new int[123];//reference type    pa[0] = AA;//The reference type data on the heap is changed to    AA = 456;//Stack The value type is changed, but the data on the heap is not synchronized, and this is not a WPF data binding, haha}

In C # code:
private void Form1_Load (object sender, EventArgs e) {            int aaa = 123;//value Type            IntPtr paaa = System.Runtime.Inte RopServices.Marshal.AllocHGlobal (sizeof (int)); Ref Type            System.Runtime.InteropServices.Marshal.WriteInt32 (PAAA,AAA);//box            AAA = System.Runtime.InteropServices.Marshal.ReadInt32 (PAAA); UnBox}

Inheritance Relationship
C # 's gadgets inherit System.Object, and the value types on the stack inherit System.ValueType, which is a compiler-defined implicit inheritance.
This is the case:
void foo () {    int aaa = 123;    System.Diagnostics.Debug.WriteLine (((AAA as ValueType) as Object). ToString ());}

So you can:
private bool Isvaluetype (object o) {            return o is ValueType? True:false;} private void Form1_Load (object sender, EventArgs e) {            int aaa = 123;            System.Diagnostics.Debug.WriteLine (Isvaluetype (AAA). ToString ()); True            var bc = new Form ();            System.Diagnostics.Debug.WriteLine (Isvaluetype (BC). ToString ()); False}


something fun.
Reference types for value types:
As you know, value types use stack memory, in C + +, we have stacks of classes (that is, RIIA, resource allocations are initialized), but in C #, all classes must use new for heap requests, which are managed uniformly by the GC.
For example, in the DirectShow Basic class, the Automatic critical section class Ccritsec, just like the lock keyword in C #.

The feature of the stack is the initialization of assignment--:
int AA = 123;
Exits automatic destruction.

This RIIA paradigm is used well in the hands of C + + programmers.
C #, because all reference types are running on the heap, what if we want to do something like RIIA?
Maybe you already think about it, using keyword and IDisposable

I'm not going to say more, I'll find out by searching.

C # Value types and reference types are understood in the English language

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.