C # value type and reference type

Source: Internet
Author: User

1. Main Content

Basic concepts of Types

In-depth Value Type

In-depth reference type

Comparison and Application of Value Type and reference type

2. Basic Concepts

In C #, whether a variable is a value or a reference only depends on its data type.

The basic data types of C # are defined in a platform-independent manner. The pre-defined types of C # are not built into the language, but are built into the. NET Framework .. . Net uses a general type System (CTS) to define predefined data types that can be used in the intermediate language (IL. net Language is eventually compiled into Il, that is, compiled into Cts-basedCode,

Common types of system functions:

    • Build a framework that supports cross-language integration, type security, and high-performance code execution.
    • Provides support for multiple full implementationsProgramming Language.
    • Defining rules that must be followed by each language helps ensure that objects written in different languages can interact with each other.

 

For example, when C # declares an int variable, it is actually an instance of system. int32 in CTS. This has important significance:

    • Ensure the security of the forced type on IL;
    • Achieves interoperability between different. NET languages;
    • All data types are objects. They can have methods, attributes, and so on. For example:

Int I;
I = 1;
String S;
S = I. tostring ();

 

CLR supports two types:Value TypeAndReference type,

 

 

All value types of C # are implicitly derived from system. valuetype:

    • Struct: struct (directly derived from system. valuetype );

      • Value Type:

        • Integer: sbyte (system. sbyte alias), short (system. int16), INT (system. int32), long (system. int64), byte (system. byte), ushort (system. uint16), uint (system. uint32), ulong (system. uint64), char (system. char );
        • Float: Float (system. Single), double (system. Double );
        • The high-precision decimal type used for financial computing: decimal (system. decimal ).
      • Bool type: bool (alias of system. Boolean );
      • User-defined struct (derived from system. valuetype ).
    • Enumeration: Enum (derived from system. Enum );
    • Can be null type (derived from system. nullable <t> generic struct, T? Is actually the alias of system. nullable <t> ).

Value Type instances are usually allocated to the stack of a thread and do not contain any pointer to the instance data, because the variable itself contains the instance data.

 

C # has the following reference types:

    • Array (derived from system. array)
    • The following types are defined by the user:
      • Class: Class (derived from system. Object );
      • Interface: interface (the interface is not a "thing", so there is no problem where it is derived. Anders said in C # programming language that an interface only represents a Convention [contract]);
      • Delegate: Delegate (derived from system. Delegate ).
    • Object (alias of system. Object );
    • String: string (alias of system. String ).

We can see that:

    • If the reference type is the same as the value type, the struct can also implement interfaces;
    • The reference type can be derived from a new type, but the value type cannot;
    • The reference type can contain null values and the value type cannot (the null type function allows null to be assigned to the value type );
    • The value assignment of the reference type variable only copies the reference to the object, instead of copying the object itself. When a value type variable is assigned to another value type variable, the included values are copied.

2.1 memory depth

2.2.1 memory mechanism

The location where data is allocated in the memory depends on the Data Type of the variable. We can see that the value type is allocated to the thread stack, and the reference type is allocated to the managed stack, which is controlled and recycled by the GC, the following code demonstrates the differences between the reference type and the Value Type:

Private Static class referencevsvalue {
// Reference type (because of 'class ')
Private class someref {public int32 X ;}

// Value type (because of 'struct ')
Private struct someval {public int32 X ;}

Public static void go (){
Someref R1 = new someref (); // allocate on the stack

Someval V1 = new someval (); // allocate on the stack
R1.x = 5; // pull pointer

V1.x = 5; // modify on Stack
Console. writeline (r1.x); // display "5"

Console. writeline (v1.x); // "5" is also displayed"
// The left half reflects the execution of the above Code

Someref r2 = R1; // copy reference only (pointer)
Someval v2 = V1; // allocate and copy members on the stack
R1.x = 8; // both r1.x and r2.x are changed.

V1.x = 9; // only v1.x is changed and v2.x is not changed.
Console. writeline (r1.x); // display "8"
Console. writeline (r2.x); // display "8"
Console. writeline (v1.x); // display "9"
Console. writeline (v2.x); // display "5"
// The right half reflects the situation after all the code is executed
}
}
Figure 5-1 memory allocation during Code Execution

 

Someval is declared using struct, rather than using common classes. In C #, struct declares the value type, each variable orProgramEach has its own stack. Different variables cannot share a memory address. Therefore, someref and someval must occupy different stacks. After the variables are passed, when V1 variables are changed, obviously, V2 data is not affected. We can see that V1 and V2 in the stack contain actual data, while R1 and R2 store the reference address of instance data in the stack, the actual data is stored in the managed heap. Therefore, different variables may store data references of the same address. When a variable of the referenced type is passed to another variable of the same referenced type, the reference address instead of the actual data is passed, so changing the value of a variable will affect the value of another variable, the allocation of value types and reference types in the memory determines the root cause of their different applications. This can easily explain why passing a parameter by value does not change the value of the parameter, passing by address changes the value of the parameter.

Memory Allocation:

    • When the value type variable is a local variable, the instance will be created on the stack. If the value type variable is a member variable of the type, it will be part of the data of the type instance, other fields of the same type are stored on the managed stack. The problem will be detailed in the subsequent nested structure section.

    • The reference type variable data is stored on the managed stack, but varies according to the instance size as follows: if the instance size is smaller than 85000byte, the instance will be created on the GC stack; when the instance size is greater than or equal to 85000byte, the instance is created on the LOH (large object heap) stack.

2.2.2 nested type

The nested structure defines the reference type nested in the value type, or the value type is nested in the reference type variable.

      • Reference Type nested Value Type

Public class nestedvalueinref
{
// Aint will be allocated to the managed stack as part of the reference type
Private int aint;
Public nestedvalueinref
{
// Achar is allocated to the thread stack of the code segment.
Char Achar = 'a ';
}
} Figure 5-2 The memory distribution chart can be expressed:

 

    • Value Type nested reference type

When the reference type is nested in the value type, the memory allocation is: The reference type will be used as a value type member variable, and the reference of this Member will be saved on the stack, the actual data of members is stored in the managed heap.

Public struct nestedrefinvalue
{
Public myclass;
Public nestedrefinvalue
{
Myclass. x = 1;
Myclass. Y = 2;
}
}

Figure 5-3 The memory distribution chart can be expressed:

1. Main Content

Basic concepts of Types

In-depth Value Type

In-depth reference type

Comparison and Application of Value Type and reference type

2. Basic Concepts

In C #, whether a variable is a value or a reference only depends on its data type.

The basic data types of C # are defined in a platform-independent manner. The pre-defined types of C # are not built into the language, but are built into the. NET Framework .. . Net uses a general type System (CTS) to define predefined data types that can be used in the intermediate language (IL. net Language is eventually compiled into Il, that is, compiled into Cts-type code,

Common types of system functions:

    • Build a framework that supports cross-language integration, type security, and high-performance code execution.
    • Provides an object-oriented model that supports the complete implementation of multiple programming languages.
    • Defining rules that must be followed by each language helps ensure that objects written in different languages can interact with each other.

 

For example, when C # declares an int variable, it is actually an instance of system. int32 in CTS. This has important significance:

    • Ensure the security of the forced type on IL;
    • Achieves interoperability between different. NET languages;
    • All data types are objects. They can have methods, attributes, and so on. For example:

Int I;
I = 1;
String S;
S = I. tostring ();

 

CLR supports two types:Value TypeAndReference type,

 

 

All value types of C # are implicitly derived from system. valuetype:

    • Struct: struct (directly derived from system. valuetype );

      • Value Type:

        • Integer: sbyte (system. sbyte alias), short (system. int16), INT (system. int32), long (system. int64), byte (system. byte), ushort (system. uint16), uint (system. uint32), ulong (system. uint64), char (system. char );
        • Float: Float (system. Single), double (system. Double );
        • The high-precision decimal type used for financial computing: decimal (system. decimal ).
      • Bool type: bool (alias of system. Boolean );
      • User-defined struct (derived from system. valuetype ).
    • Enumeration: Enum (derived from system. Enum );
    • Can be null type (derived from system. nullable <t> generic struct, T? Is actually the alias of system. nullable <t> ).

Value Type instances are usually allocated to the stack of a thread and do not contain any pointer to the instance data, because the variable itself contains the instance data.

 

C # has the following reference types:

    • Array (derived from system. array)
    • The following types are defined by the user:
      • Class: Class (derived from system. Object );
      • Interface: interface (the interface is not a "thing", so there is no problem where it is derived. Anders said in C # programming language that an interface only represents a Convention [contract]);
      • Delegate: Delegate (derived from system. Delegate ).
    • Object (alias of system. Object );
    • String: string (alias of system. String ).

We can see that:

    • If the reference type is the same as the value type, the struct can also implement interfaces;
    • The reference type can be derived from a new type, but the value type cannot;
    • The reference type can contain null values and the value type cannot (the null type function allows null to be assigned to the value type );
    • The value assignment of the reference type variable only copies the reference to the object, instead of copying the object itself. When a value type variable is assigned to another value type variable, the included values are copied.

2.1 memory depth

2.2.1 memory mechanism

The location where data is allocated in the memory depends on the Data Type of the variable. We can see that the value type is allocated to the thread stack, and the reference type is allocated to the managed stack, which is controlled and recycled by the GC, the following code demonstrates the differences between the reference type and the Value Type:

Private Static class referencevsvalue {
// Reference type (because of 'class ')
Private class someref {public int32 X ;}

// Value type (because of 'struct ')
Private struct someval {public int32 X ;}

Public static void go (){
Someref R1 = new someref (); // allocate on the stack

Someval V1 = new someval (); // allocate on the stack
R1.x = 5; // pull pointer

V1.x = 5; // modify on Stack
Console. writeline (r1.x); // display "5"

Console. writeline (v1.x); // "5" is also displayed"
// The left half reflects the execution of the above Code

Someref r2 = R1; // copy reference only (pointer)
Someval v2 = V1; // allocate and copy members on the stack
R1.x = 8; // both r1.x and r2.x are changed.

V1.x = 9; // only v1.x is changed and v2.x is not changed.
Console. writeline (r1.x); // display "8"
Console. writeline (r2.x); // display "8"
Console. writeline (v1.x); // display "9"
Console. writeline (v2.x); // display "5"
// The right half reflects the situation after all the code is executed
}
}
Figure 5-1 memory allocation during Code Execution

 

Someval is declared using struct instead of using common classes. In C #, struct declares the value type, and each variable or program has its own stack, different variables cannot share a memory address, so someref and someval must occupy different stacks. After the variables are passed, changing the V1 variable will obviously not affect the data of V2, we can see that V1 and V2 in the stack contain actual data, while R1 and R2 store the reference address of the instance data in the stack, and the actual data is saved in the managed heap, therefore, different variables may store data references of the same address. When a referenced type variable is passed to another referenced type variable, the reference address instead of the actual data is passed, so changing the value of a variable will affect the value of another variable, the allocation of value types and reference types in the memory determines the root cause of their different applications. This can easily explain why passing a parameter by value does not change the value of the parameter, passing by address changes the value of the parameter.

Memory Allocation:

    • When the value type variable is a local variable, the instance will be created on the stack. If the value type variable is a member variable of the type, it will be part of the data of the type instance, other fields of the same type are stored on the managed stack. The problem will be detailed in the subsequent nested structure section.

    • The reference type variable data is stored on the managed stack, but varies according to the instance size as follows: if the instance size is smaller than 85000byte, the instance will be created on the GC stack; when the instance size is greater than or equal to 85000byte, the instance is created on the LOH (large object heap) stack.

2.2.2 nested type

The nested structure defines the reference type nested in the value type, or the value type is nested in the reference type variable.

      • Reference Type nested Value Type

Public class nestedvalueinref
{
// Aint will be allocated to the managed stack as part of the reference type
Private int aint;
Public nestedvalueinref
{
// Achar is allocated to the thread stack of the code segment.
Char Achar = 'a ';
}
} Figure 5-2 The memory distribution chart can be expressed:

 

    • Value Type nested reference type

When the reference type is nested in the value type, the memory allocation is: The reference type will be used as a value type member variable, and the reference of this Member will be saved on the stack, the actual data of members is stored in the managed heap.

Public struct nestedrefinvalue
{
Public myclass;
Public nestedrefinvalue
{
Myclass. x = 1;
Myclass. Y = 2;
}
}

Figure 5-3 The memory distribution chart can be expressed:

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.