zoukankan      html  css  js  c++  java
  • C# 堆VS栈 值类型VS引用类型

    最近博客园上连续出现了几篇关于堆VS栈 值类型VS引用类型的文章。

    一个是关于C# 堆VS栈的,深入浅出,动图清晰明了,链接如下

    C#堆栈对比(Part One)

    C#堆栈对比(Part Two)

    C#堆栈对比(Part Three)

    C#堆栈对比(Part Four)

    二是从Eric Lippert(Eric Lippert is a principal developer on the C# compiler team)的文章演变出的两篇,链接如下

    The Truth About Value Types

    你真的了解C#中的值和引用吗?(上)

    匹夫细说C#:不是“栈类型”的值类型,从生命周期聊存储位置

    下面是我的思考和总结,希望能与大家分享和讨论。

    值类型和引用类型的区别

    最近和同事一起面试时也经常问这个问题,被面的同学很多回答为“值类型存储在栈里,引用类型存储在堆里”,首先我们先不去深究这个说法是否准确(上面的文章里已经说的很清楚)。

    值类型和引用类型的区别是存储位置的不同吗

    Eric Lippert给出的答案----值类型和引用类型的区别在语义层面,与存储位置无关。存储位置是C#编译运行时的分配,是实现细节。

      或许C# compiler的未来版本中,值类型也可能不存储在栈里;

      或者某一个系统平台中并不存在堆和栈的概念。

    结论

      “值类型和引用类型的区别,与存储位置无关”。

    值类型和引用类型区别是什么呢?

    Eric Lippert说 - 值类型和引用类型的区别在语义层面。要怎么理解?我们思考的视角应该是C#语言语义和使用上。

    结论

      “值类型传递的是值(不同的实例,互不影响),引用类型传递的是引用(同一个实例,互相影响)

        如同一句废话!那我们试着换几种方式来描述(可能不准确

        1. 值类型是私有的,是持有者自己的东西;引用类型是共享的,大家共有的东西。

        2. 值类型是多实例的,每次传递都创建新实例;引用类型是单实例的,每次传递都是同一个实例,如设计模式中的单例。

        3. 值类型的生命周期和持有者相同;引用类型的生命周期和持有者不同。(有关生命周期的言论)

    为什么在讨论值类型和引用类型时,总会出现堆和栈?

    如何实现值类型和引用类型的存储?

      有两种存储方式可供选择

        一 直接存储的优点是性能高,缺点是共享不方便。(栈或者堆上

        二 间接存储的优点是共享方便,缺点是多了一次跳转,有性能损失。(堆上

    我们要的关注哪些问题?性能,共享方式(生命周期)

      值类型是不共享的,它的生命周期和持有者相同,所以可以直接存储,如果间接存储,会多一次跳转,没有意义的性能损失。

      引用类型是共享的,它的生命周期和持有者不同,所以采用间接存储,如果直接存储,是很难实现共享和生命周期的不同。

    结论

      值类型是直接存储,引用类型是间接存储。是基于实现的考量,不是值类型和引用类型的区别。

      生命周期是从实现角度思考的推论,也不是值类型和引用类型的区别。

    为什么存在两种类型(值类型和引用类型),而不仅仅是一种类型(值类型或者引用类型)?

    思考后发现,所有值类型都可以被引用类型所替代,那为什么要有值类型呢?没有得出理想的答案,推测有两种可能

      一 历史传承。

      二 基于性能的考量。这个应该是实现级别的事情,为什么被暴露在语言级别上?没有办法解决吗?(对于值来说,引用类型多了一次跳转;对于引用来说,值的传递多了一次深克隆)

    何时用值类型(struct),何时用引用类型(class)?

    在工作中很少(几乎没有)使用struct,因为性能上的收益远远无法弥补维护成本的损失

    (不能要求每个开发人员都很了解struct和class的不同,并在修改代码时意识到使用的是struct而不是class)

    总结

    值和引用类型的区别是语言和使用级别的

    值类型传递的是值(不同的实例,互不影响),引用类型传递的是引用(同一个实例,互相影响)

    有关值类型和引用类型储存在栈或者堆上的言论,是基于实现细节的思考,是当前的实现方式,不是值类型和引用类型的区别。

    有关值类型和引用类型生命周期的言论,是基于实现细节的思考,是当前的实现方式,不是值类型和引用类型的区别。

    值类型(struct)更多是性能上的收益,C#中定义的基础值类型已经足够,开发中尽量避免定义值类型(struct)

    期待看到不同的观点和理由!

     

  • 相关阅读:
    条件随机场(Conditional random field)
    隐马尔科夫模型(hidden Markov Model)
    什么是EM算法?
    非线性支持向量机基础——核函数之我见
    支持向量机(support vector machine)
    决策树之CART算法
    决策树到底是什么?
    pytorch下对简单的数据进行分类(classification)
    git status 命令
    spring中事务的实现方式和失效场景
  • 原文地址:https://www.cnblogs.com/xujiaoxiang/p/4431862.html
Copyright © 2011-2022 走看看