• 一道面试题引发的思考(C#值类型和引用类型)


    某年某月,笔者去面试招行的一个外包项目,辗转来到面试地点以后,面试官给了我一份试卷,试卷只有两道题目,其中一道是这样的:

    阅读以下程序

     1  class Program
     2     {
     3         struct Point
     4         {
     5            public int x;
     6            public int y;
     7             public Point(int x,int y)
     8             {9
     9                 this.x = x;
    10                 this.y = y;
    11             }
    12         }
    13 
    14  
    15         static void Main(string[] args)
    16         {
    17             Point p1 = new Point(100,100);
    18             Point p2 = p1;
    19             p1.x = 200;
    20             Console.WriteLine("{0},{1}", p1.x, p2.x);
    21             Console.ReadLine();
    22 
    23         }
    24  }

    请写出p1.x和p2.x的值。

       笔者属于那种基础不是很扎实的那种码农,平时也就是个CURD Boy,虽然明白这道题是考察变量在内存中的分配,但是之前没怎么在意这方面的问题,一时间竟然答不上来。

      其实这道题目只要理解Struct结构是值类型的变量就好了。所谓的值类型,在概念上讲,就是直接存储变量的值。那么Point p2=p1这一句的意思就是在内存(堆栈)的另一个地方创建一个一模一样的变量p2,p2和p1值相同,但是是两个完全不同的变量,改变p1的值不影响p2,所以最后p1.x=200,p2.x=100.

      如果将题目中的struct改为class,即代码变成了这样:

      class Program
        {
            class Point
            {
               public int x;
               public int y;
                public Point(int x,int y)
                {
                    this.x = x;
                    this.y = y;
                }
            }
    
     
            static void Main(string[] args)
            {
                Point p1 = new Point(100,100);
                Point p2 = p1;
                p1.x = 200;
                Console.WriteLine("{0},{1}", p1.x, p2.x);
                Console.ReadLine();
    
            }
     }
    

      结果又是怎么样呢?

       答案是p1.x=200,p2.x=200。因为在C#中,Class是引用类型,p1和p2其实指向同一块内存区域,修改p1的指向值会影响p2指向的值。有点类似于C#的指针。

       总结一下,就是C#的数据类型分为值类型和引用类型两种。值类型存储变量的值,引用类型存储变量的引用。二者可以存储的地方不同,值类型存储在堆栈中,引用类型存储在托管堆上。关于堆栈和托管堆,需要进一步展开学习。

       这里有一个例外,当引用类型为string的时候,修改其中一个字符串,会得到一个全新的string对象,和值类型一致,而另一个字符串不会发生变化。这是由于运算符重载的结果。

    功成归故里,种豆南山下。竹丝吟风月,诗酒趁年华。
  • 相关阅读:
    聊聊 node 如何优雅地获取 mac 系统版本
    VUE引入@wecom/jssdk,使用应用的jsapi_ticket,通过agentConfig注入应用
    前端知识学习03
    前端知识学习01
    前端知识学习02
    前端知识学习04
    主流开源分布式图计算框架 Benchmark
    一文带你了解 「图数据库」Nebula 的存储设计和思考
    macOS 安装 Nebula Graph 看这篇就够了
    BIGO 的数据管理与应用实践
  • 原文地址:https://www.cnblogs.com/wangwangmiao/p/9013813.html
Copyright © 2020-2023  润新知