C # value type and reference type learning

table of Contents

1 Introduction

2. Concept

Value type

Reference type

string exploration

3. Common System Type (CTS)

4. The deployment of value types and reference types in memory

Understanding of stacks and heaps

Stack

stack

Allocation of value types and reference types on the stack and heap

5. Value type and reference type applicable occasions

reference


1 Introduction

I have been learning C # for almost two years. I have n’t been into C and C ++ before, but I do n’t know the basics, so I did n’t spend too much time on the basics when learning C #. I'm going to find a job, I think I still have to learn the basics. Today, let's take a look at the difference between C # value types and reference types.

2. Concept

There are two basic types in c #, they are value type and reference type

Value type

Variables are stored directly in memory, and byte, short, int, long, float, double, decimal, char, bool, and struct are collectively called value types. All value types are implicitly sealed (new value types cannot be derived), the purpose is to prevent any other types from deriving from value types. After the value type variable is declared, the compiler allocates memory for it whether or not it has been assigned.

All value types of C # are implicitly derived from System.ValueType:

Structure: struct (derived directly from System.ValueType);
value type:

  • 整型:sbyte(System.SByte的别名),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(System.Single),double(System.Double);
  • decimal (System.Decimal), used for high precision in financial calculations.
  • bool type: bool (alias for System.Boolean);
  • struct (derived from System.ValueType).
  • enum (derived from System.Enum);
  • Nullable type (derived from System.Nullable <T> generic structure, T? Is actually an alias of System.Nullable <T>).

It is worth noting that both reference types and value types inherit from the System.Object class. The difference is that almost all reference types inherit directly from System.Object, while value types inherit their subclasses, that is, directly inherit System.ValueType. System.ValueType is directly derived from System.Object. That is, System.ValueType itself is a class type, not a value type. The key is that ValueType rewrites the Equals () method, so that the value type is compared according to the value of the instance, not the reference address.

You can use the Type.IsValueType property to determine whether a type is a value type:

TestType testType = new TestType ();
if (testTypetype.GetType().IsValueType)
{
     Console.WriteLine("{0} is value type.", testType.ToString());
}

Reference type

Reference type variables hold references to data. The data is stored in the data heap. String and class are collectively called reference types. When declaring a class, only a small piece of memory is allocated on the stack to hold an address, and no memory space on the heap is allocated for it at this time . When using new to create an instance of a class, allocate space on the heap, and save the address of the space on the heap to the small space allocated on the stack.

C # has the following reference types:

  • Array (derived from System.Array)
  • The user defines the following types:
  • Class: class (derived from System.Object);
  • Interface: interface (Interface is not a "something", so there is no question of where it is derived. Anders said in "C # Programming Language", the interface is just a convention [contract]);
  • Delegate: delegate (derived from System.Delegate).
  • object (alias of System.Object);
  • String: string (alias of System.String).

string exploration

Obviously string assignments are all value types, what about reference types?

The .net framework programming (revised edition) has this description:

The string type directly inherits Object, which makes it a reference type, which means that no string will reside on the thread's stack.

name

CTS type

Explanation

string

System.String

Unicode string

string s1 = "aaaa";
 
string s2 = s1;
 
Console.WriteLine("s1:" + s1);
 
Console.WriteLine("s2:" + s2);
 
s1 = "bbbb";
 
Console.WriteLine("s1:" + s1);
 
Console.WriteLine("s2:" + s2);
 
Console.ReadKey();

On the String string, the S1 address initially points to aaaa. Since S2 = S1, the S2 address also points to aaaa. as the picture shows

When bbbb is assigned to S1 again, the data bbbb will be opened in the heap, and the aaaa data has not disappeared and has not been overwritten. S1 address will point to bbbb in the heap

The S2 address still points to aaaa. as the picture shows

The above code assigns value types, but string is a reference type. String is allocated on the heap, not on the stack. Therefore, when you assign a string variable to another string, you will get two references to the same string in memory. However, string and reference types have some differences in common operations. For example, the string is immutable. Modifying one of the strings will create a brand new string object, while the other string will not change.

3. Common System Type (CTS)

The basic data types of C # are defined in a platform-independent manner. The predefined types of C # are not built into the language, but built into the .NET Framework. All .NET-oriented languages ​​are eventually compiled into IL.

For example, when an int variable is declared in C #, it is actually an instance of System.Int32 in CTS. This has important implications:
ensuring mandatory type safety on IL;
achieving interoperability between different .NET languages; and
all data types are objects. They can have methods, properties, etc. For example: ToString ().

4. The deployment of value types and reference types in memory

Understanding of stacks and heaps

Stack

The stack can only operate on data at one end, that is, at the top of the stack. '

The stack is also a self-management structure of memory. Pushing the stack automatically allocates memory, and popping the stack automatically clears the occupied memory.

  Two other points worth noting:

     1. The memory in the stack cannot be requested dynamically, and the memory can only be allocated for data of a certain size. The flexibility is not high, but the execution efficiency of the stack is very high .

     2. The available space on the stack is not large, so we should pay attention to the impact of the size of the data when operating the data allocated to the stack.

stack

   The heap is different from the stack. The heap is used to store real instance objects in C #, which can store a large amount of data, and the heap can dynamically allocate storage space .

   Compared with the stack can only be operated at one end, the data in the heap can be accessed at will .

   However, the structure of the heap makes the execution efficiency of the heap not as high as the stack, and it cannot automatically recycle used objects. For the memory recovery in the heap, C ++ programmers need to perform manual recovery, which is also worth noting in C ++ programming, otherwise it is easy to cause memory overflow. For .NET programmers, the platform provides a garbage collection (GC) mechanism that can automatically collect expired objects in the heap.

Allocation of value types and reference types on the stack and heap

There are two principles here:

    (1) When creating a reference type, the runtime will allocate two spaces for it. One space is allocated on the heap to store the data of the reference type itself, and the other block space is allocated on the stack to store the reference to the data on the heap (actually The memory address on the stored heap, that is, the pointer).

    (2) When creating a value type, the runtime will allocate a space for it. This space is allocated where the variable is created , such as:

      If the value type is created inside the method, then the method is pushed onto the stack and allocated to the stack for storage.

      If the value type is a member variable of a reference type, it follows the reference type and is stored on the heap.

More detailed introduction reference: https://blog.csdn.net/qiaoquan3/article/details/51202926

5. Value type and reference type applicable occasions

Value types have better efficiency in memory management, and do not support polymorphism, suitable for use as a carrier for storing data; reference types support polymorphism, suitable for defining application behavior.

In C #, we use struct / class to declare a type as a value type / reference type. Consider the following example:
SomeType [] oneTypes = new SomeType [100];
If SomeType is a value type, you only need to allocate it once, and the size is 100 times the size of SomeType. If SomeType is a reference type, it needs to be allocated 100 times at the beginning. After the allocation, each element value of the array is null, and then 100 elements are initialized, resulting in a total of 101 allocations. This will consume more time and cause more memory fragmentation. Therefore, if the responsibility of the type is mainly to store data, the value type is more appropriate.
In general, the value type (does not support polymorphism) is suitable for storing data for C # application operations, and the reference type (supports polymorphism) should be used to define the behavior of the application. Usually we create more reference types than value types. If the following conditions are met, then we should create a value type:
the main responsibility of this type is used for data storage. 
The common interface of this type is completely defined by some data member access attributes. 
This type can never have subclasses. 
This type does not have polymorphic behavior.
 

reference

Reference types and value types in C #

Value types and reference types in C #

Is the string type a value type or a reference type in C #?

C # explain the difference between value types and reference types

Published 30 original articles · Like1 · Visits1158

Guess you like

Origin blog.csdn.net/chunchunlaila/article/details/105472903