当前位置:网站首页>Value passing and reference passing of value types and reference types in CSharp

Value passing and reference passing of value types and reference types in CSharp

2022-06-24 18:39:00 MousseIn


In order to consolidate Csharp The basic knowledge of , In the process of laying the foundation for the upcoming interview , I found a strange thing , It is the value type and reference type that I use , And the value type 、 The definitions and expressions of various passes of reference types represent various incomprehensions and confusion , I want to use as a C# As a language for software development, quasi software development engineers , It is necessary .

Heap and stack

To figure out what is a value type and what is a reference type , The first thing I thought about was , This thing is the same thing that you want to use , I don't quote more terms and definitions to avoid making myself look confused when I look back , But first of all , Since both the value type and the reference type are “ thing ”, Or something to pass “ goods ”, Express delivery in real life , All need a warehouse or even a carriage to store express mail , So the concept to be introduced here is used to store the value type and reference type “ goods ” Such a place —— Heap and stack

Pile up

This thing is literally easy to understand , It is a blank place , Just build something up , But readers with a slightly better language or a slightly more accurate sense of language may find ( I didn't say that I despise people who have a bad sense of language ), Our pile , It sounds like a pile of things stored in a certain area . for instance —— A jumble of books , Etc., etc. .

What is the heap for ?

To Liao ! This C# in , The function of the heap is to store C# Medium Instance object , Of course , Who has nothing to do to write a project and deliver it in one day “ thing ” All are Instance object ? Of course, data should also be stored ! And it's a lot of data !( Don't ask me how much this is ,emmmm)

What are the characteristics of heaps ?

When I was sorting out the materials , I found myself asking the most questions , This is this. .
Think from its Chinese name , Heap is used to describe messy Of ( If it's orderly , I prefer to use Group To describe ) If you think so , To Liao ! This is the first feature .

  1. The stored data or instance object is disorder Of .
  2. Since there is no order , Of course you can access whatever you want data Or is it Instance object La !
  3. And you can Dynamic allocation Storage space .

So what's wrong with the pile ?

Yes, yes , That is, the reading speed is relatively slow and the expired data cannot be automatically recycled Instance object ( Of course .net Yes GC however C++ The contestants were a little miserable ……).
Because there is no order , You are making a request to the system , I'm looking for XX XX data ! The system will find what you are looking for from the heap , It's like looking for your favorite comic book in the stack of books . So time will be a little slower .

Stack

It's too much to say , Let's talk about the term stack .

What the stack looks like relative to the heap ?

Simply speaking , You can think of a stack as “ Leshi's potato chip bucket ”.

So what are the characteristics of stack ?

Stack versus heap , It seems very intelligent .
You pick up one “ Leshi's potato chip bucket ” With a bottom at the back , You put potato chips in it one by one. Pick them up and put them in , Right ? If the first film “ Potato chips ” What you put in is coke , The second piece you put in is lime and cucumber , The third piece is roast meat , And it suddenly occurred to you , Well, I haven't eaten coke flavored potato chips yet , Now , You want to take it out . So you have to take out the two potato chips on it first , Then take out the bottom potato chips .
Characteristic is !

  • The stack can only operate at one end ! That's what we're talking about “ The mouth of the potato chip bucket ”, But we usually call it To the top of the stack , Storage is like “ Le Shi crisps bucket ” The same way you store potato chips “ First in, then out , First out, then in ” Principles .
  • Is a kind of the stack Memory self-management Structure , Automatically allocate memory when data is put on the stack , The stack automatically empties the memory occupied .
  • Although it looks like a stack , The process of accessing data is troublesome , however ! His performance efficiency in multiple data is faster than Pile up Of this storage method .

There is nothing wrong with storing data in stack mode ?

Yes. ! There are two sides to everything !

  • The memory in the stack cannot Dynamic request , Namely , Can only be allocated according to the data size , Flexibility is not as high as heap .
  • Like “ Le Shi crisps bucket ” Like the potato chips in , Only a certain amount of data can be stored , Therefore, we should consider the impact of data size when using .

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

There are actually two rules here !

  • When creating reference types , Memory management will allocate a piece of space in the heap , Then allocate a piece of memory to the stack , Used to store the memory address in the heap !( Yes, the pointer ..........)

  • When creating value type data , Memory management will allocate a piece of memory for him , Then this memory is placed in the value type data establish The place of .
    To be honest, I didn't understand it at first , Especially the words "where it was created" , But I thought for a while ( Omnipotent language ) There are two situations :

  • If the value type data is created inside the method , Then his memory address will be put on the stack following the method .

  • If the value type data is a member variable of a reference type , Then his memory address will be stored in the heap following the reference type .

Value type

What is a value type ? I have no definition , But the information collected clearly points out that :byte,short,int,long,float,double,decimal,char,bool and struct These brothers are collectively referred to as value types .

Reference type

C# The reference types in are :class and string

The essential difference between value type and reference type :

  1. The value type is assigned to Thread stack On ( Management is the responsibility of the operating system ), The reference type is assigned to Managed heap On ( Managed by the garbage collector GC be responsible for ). Management here refers to , Memory allocation and recycling .
  2. Value types inherit from valueType,valueType Inherited from System.Object; Reference types inherit directly from System.Object.
  3. When a value type ends in scope , Will be released by the operating system , Reduce managed heap pressure ; The reference type depends on GC. Therefore, the value type has advantages in performance .

Value passed

Pass it by value !

Value passing of value type

What also don't say ! Go straight to the code !

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static System.Console;

namespace Test3
{
    
    class Program
    {
    
        static int pass(int PassNum, int PassNum2)
        {
    
            int MaxNumber = PassNum + PassNum2;
            return MaxNumber;
        }
        static void Main(string[] args)
        {
    
            int Maxnumber1 = 6;
            int Maxnumber2 = 7;
            int ShowMax = pass(Maxnumber1, Maxnumber2);
            WriteLine(ShowMax);
            ReadLine();
        }
    }
}

The running result is : Insert picture description here
You can see that the running result is 13.
The parameter passing is the value type passing . The value type copies the data itself , Form independent data blocks .

Value passing of reference type :

Continue up code !

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static System.Console;
namespace Test4
{
    
    class Program
    {
    

        static void ChangeArray(int[] CArray)
        {
    
            CArray[0] = 888;
            CArray = new int[5] {
     -3, -2, -1, -3, -4 };
            WriteLine(" In this way , The first element is ,{0}", CArray[0]);

        }

        static void Main(string[] args)
        {
    
            int[] CArray = {
     1, 2, 3, 4, 5 };
            WriteLine(" stay Main Inside ,ChangeArray Before method call , The first element of the array is ,{0}", CArray[0]);

            ChangeArray(CArray);
            WriteLine(" stay Main Inside ,ChangeArray After method call , The first element of the array is ,{0}", CArray[0]);
            ReadLine();
        
        }
    }
}

In fact, when I was writing this example , I'm crazy about calling ChangeArray After this function , How the array in the parameter is {888,2,3,4,5}, In my imagination , Should be {888,-2,-1, -3, -4}:new And changed the array pointer in the passed in method .
Again , At the beginning of the program ,Main Method to give value :Main Method to give value
Pass the reference type value to the post method address : Pass the reference type value to the post method address
new An array of Changed the array pointer in the incoming method .
new An array of Changed the array pointer in the incoming method
After calling method , An array of the same address changes the first value , So the first number is 888. Because you can see from the address pointer of the array , After the method is called CArray Array is actually the beginning Main Declarative CArray, Not later in the method new And assigned CArray. After calling method , An array of the same address changes the first value , So the first number is 888. Because you can see from the address pointer of the array , After the method is called CArray Array is actually the beginning Main Declarative CArray, Not later in the method new And assigned CArray.
Running results : Running results
From this, we can see that when a value passes reference type data , Although it is a copy, it will create a new address , Turning an array into actually two addresses , Store different values separately , To call .

reference

Reference passing of value type :

Code up !

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static System.Console;

namespace Test3
{
    
    class Program
    {
    
        static int pass(ref int PassNum,ref int PassNum2)
        {
    
            int MaxNumber = PassNum + PassNum2;
            return MaxNumber;
        }
        static void Main(string[] args)
        {
    
            int Maxnumber1 = 6;
            int Maxnumber2 = 7;
            int ShowMax = pass(ref Maxnumber1, ref Maxnumber2);
            WriteLine(ShowMax);
            ReadLine();
        }
    }
}

What is the difference from the above ? Namely ref!
With this “ Prefix ”, You have to understand :
In this case , The message is not Maxnumber1 and Maxnumber2 In itself , It's their quote . Parameters in method PassNum and PassNum2 No int type , It's right int Type of quote .

Reference passing of reference types :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static System.Console;
namespace Test4
{
    
    class Program
    {
    

        static void ChangeArray(ref int[] CArray)
        {
    
            CArray[0] = 888;
            CArray = new int[5] {
     -3, -2, -1, -3, -4 };
            WriteLine(" In this way , The first element is ,{0}", CArray[0]);

        }

        static void Main(string[] args)
        {
    
            int[] CArray = {
     1, 2, 3, 4, 5 };
            WriteLine(" stay Main Inside ,ChangeArray Before method call , The first element of the array is ,{0}", CArray[0]);

            ChangeArray( ref CArray);
            WriteLine(" stay Main Inside ,ChangeArray After method call , The first element of the array is ,{0}", CArray[0]);
            ReadLine();
        
        }
    }
}

There is no mystery , Directly changed the address .
Reference passes a reference to an instance of a type main Method to give value : Reference passes a reference to an instance of a type main Method to give value
After entering the method , because new The array address and array value are changed : After entering the method , because new The array address and array value are changed
Until the end of the run , The address hasn't changed .
The operation results are as follows : Running results
You can see , After the referenced method passes the reference parameter , The array address pointer is added without copying the array , Change the value in the original new array , So the output is -3 instead of 888.

use return Instead of passing by reference :

Actually, this is the homework that the teacher left for me !
Code up !

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static System.Console;
namespace Test4
{
    
    class Program
    {
    

        static int[] ChangeArray( int[] CArray)
        {
    
            CArray[0] = 888;
            CArray = new int[5] {
     -3, -2, -1, -3, -4 };
            WriteLine(" In this way , The first element is ,{0}", CArray[0]);
            return CArray;
        }

        static void Main(string[] args)
        {
    
            int[] CArray = {
     1, 2, 3, 4, 5 };
            WriteLine(" stay Main Inside ,ChangeArray Before method call , The first element of the array is ,{0}", CArray[0]);

             CArray = ChangeArray(CArray);
            WriteLine(" stay Main Inside ,ChangeArray After method call , The first element of the array is ,{0}", CArray[0]);
            ReadLine();
        
        }
    }
}

It was originally a value transfer , To get the effect of reference passing : Let's use the array in the method return Efferent , And in mian Method to create a variable to accept , Of course Variable names can be different , To indicate that the outgoing array is a copied array after the value is passed .
The operation results are as follows :
return The law changes
To this end ! Thank you. !

原网站

版权声明
本文为[MousseIn]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/02/202202211332353683.html