• CSharp进阶 引用类型引发的血案


    CSharp 里有值类型和引用类型的说法,不知各位看官清楚这两个坏人不,我也是今天才知道他们的使坏之处.

    首先,值类型字面上的意思,便是值;引用类型,便是引用.举个简单的例子我与"我",这两个是完全不同的意思,我→单单表示说这字时,是本人在说话;"我"→表示别人在说话.就是这个理.如果要在程序上体现出来的话,则是这样:

    1 int me = 0; //这是一个值类型

    2 object oMe = me;//这是一个引用类型

    也许到这儿,你会觉得没有多大的区别,但实际上,me是存在物理地址上;oMe也是存在物理地址上,但oMe存的东西跟me是不一样的,me所存的就是0的机器码,oMe存的是me的地址.我想,这样子你应该就清楚了.也就是说,oMe存的是一个地址.

    如果单单是上面这么简单也就罢了,但是现在,我做如下操作,血案就产生了.

    3 object oMe = 0;

    4 int me = (int)oMe;

    这两句话看似很简单,但它们做的坏事可真不少.首先oMe是一个引用类型,它能够产生,就必须分配两块物理内存,一个存0,一个存0所在的物理地址.

    当执行第二句话的时候,这里就更复杂了,先找到oMe所存的值,然后进行类型转换,分配给me物理内存,存下转换后的值.

    这就是这两句话所做的事.但实际却又不是这样的.

    2执行的时候,其实做了一个强制类型转换(把int转换成object),这个过程叫装箱.

    4执行的时候,也做了一个强制类型转换(把objct转换成int),这个过程叫拆箱.

    这就是引发的血案,CSharp传说中的装箱拆箱.同时,也引发了托管这个叫人伤心的东西,然后扩散到.NetFrameWrok与CTS的区别.

    我们再深入一下:

    值类型→放在堆栈里

    引用类型→放在托管堆里

    也就是说,堆栈→托管堆的过程就是装箱;托管堆→堆栈的过程就是拆箱.

    上面我们提到了.NetFrameWrok与CTS的区别,我记得一个同事问过我这样子的一个问题:"你知道int与Int32区别么?" 说实话,那个时候,我还真不知道.只知道在CSharp中,这两个都可以用,当时我的回答是这样的:"Int32是一个类."这个回答只答对了一半,其实最根本的是这样子的:

    int 是.NetFrameWrok提供的,Int32是通用类型系统CTS提供的.这就是它们最根本的区别.

    int _net = null;//错误,如果真想给null,那么必须这样使用 int? _net = null;

    Int32 _cts = null;//错误,如果真想给null,那么必须这样使用 Int32? _net = null;

    那么,加上?为什么可以赋值null呢,DBNull.Value与null的区别是什么呢?

    不知我这样子说明,大家清楚了没有.

  • 相关阅读:
    Go 单元测试、基准测试、并发基准测试
    Go url编码和字符转码
    ssh 登录进入 docker container
    Python 开发
    Ethereum 源码分析之 accounts
    Ethereum 源码分析之框架
    数据库视图
    共识算法:PBFT、RAFT
    JQuery Mobile
    Android Studio
  • 原文地址:https://www.cnblogs.com/d1eec7bf/p/4370245.html
Copyright © 2020-2023  润新知