.NET:也谈谈.NET中的引用类型和值类型

背景

引用类型和值类型的区别好像是一个经典的面试问题,也是一个非常基础的问题,今天试着写一下,一则为了以后新入职的毕业生学习,二则希望高手批评。

几个事实

  • 值类型的局部变量始终分配在栈中,局部变量中存储的是值。
  • 引用类型的局部变量始终分配在栈中,局部变量中存储的是值地址(引用),地址指向的值(对象)分配在堆中。
  • 值类型的成员变量始终内敛存储在对象中(堆中),内敛存储的是值。
  • 引用类型的成员变量始终内敛存储在对象中(堆中),内敛存储的是值地址(引用),地址指向的值(对象)分配在堆中的另外一个区域。
  • 一个进程拥有多个AppDomain。
  • 一个AppDomain拥有一个堆。
  • 一个进程可以运行多个线程。
  • 一个线程拥有一个栈(对于理解多线程编程非常有用)。
  • 一个AppDomain中的所有线程之间共享一个堆(对于理解多线程编程非常有用)。
  • 随着函数的调用和返回栈在不停的生长(调用)和消减(返回)。
  • .NET默认是按值传递参数的。
  • ref和out会导致按地址传递(栈的地址),也叫按引用传递。

注意事项:不要用C#中的这些事实理解Javascript、Ruby和Python等动态语言,一般会适得其反。

一个小测试

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 
 7 namespace StackAndHeapStudy
 8 {
 9     class Program
10     {
11         static void Main(string[] args)
12         {
13             {
14                 var p = new Program();
15                 Console.WriteLine(p.GetHashCode());
16                 Do(ref p);
17                 Console.WriteLine(p.GetHashCode());
18             }
19             {
20                 var p = new Program();
21                 Console.WriteLine(p.GetHashCode());
22                 Do(p);
23                 Console.WriteLine(p.GetHashCode());
24             }
25         }
26 
27         static void Do(ref Program p)
28         {
29             p = new Program();
30         }
31 
32         static void Do(Program p)
33         {
34             p = new Program();
35         }
36     }
37 }

备注

先把一些事实列出来,如果有朋友不是很明白,我再针对问题继续细化吧。

原文地址:https://www.cnblogs.com/happyframework/p/3133310.html