C#值类型装箱后能改变其值吗
当把一个值类型赋值给引用类型,这个过程可以看作是"装箱"。
object a = 10;
以上,堆栈上的过程大致是:
1、在栈上开辟空间给变量a
2、在堆上开辟空间,习惯上把该空间看作是"箱子"
3、把10"装箱"
变量a指向堆上值为10的对象,换句话说,变量a的值是堆上对象的地址。
现在,如果我们想让a=11,可能首先想到的是:让"箱子"内的10自增1,变成11。
尝试这样做:
oject a = 10;
a++;
结果报错:++无法运用于object类型。也就是说,++无法应用于引用类型。
那好办,先拆箱变成值类型,然后自增1呢?
object a = 10;
((int)a)++;
结果还是报错:增量或减量运算符的操作数必须为变量、属性或索引器。
((int)a)++,相当于10++,相当于10=10+1,相当于10=11,难怪会报错!
好吧,++帮不了我们,但我们可以把拆箱后的值赋值给另外一个变量:
object a = 10;
int temp = (int)a;
a = temp + 1;
这样,a的值就是11了。
这次,堆栈上大致是这样:
1、在栈上开辟空间给变量a
2、在堆上开辟空间,习惯上把该空间看作是"箱子"
3、把10"装箱"
4、在栈上开闭空间给变量temp
5、把a的值拆箱后,赋值给变量temp,此时temp的值为10
6、在堆上又开辟另外的空间
7、把temp + 1,即11装箱
变量指向堆上值为11的对象。堆上值为10的对象则等待GC的回收。
当然,以上的做法是"曲线救国",完全可以这样:
object a = 10;
a = 11;
之所以这样绕,是因为想在原先值的基础上得到新的值。
最后,回到本篇的主题:值类型装箱后能改变其值吗?答案是不能。装箱后的值具有"恒定性(Immutable)"的特点。就像本篇中的object a = 10,如果想给引用类型变量a赋上新的值,就直接a=11,就可以了。10一旦装箱,就无法改变其值了。
C#值类型装箱后能改变其值吗的更多相关文章
- NET中的引用类型和值类型 zt
.NET中的类型分为值类型和引用类型,他们在内存布局,分配,相等性,赋值,存储以及一些其他的特性上有很多不同,这些不同将会直接影响到我们应用程序 的效率.本文视图对.NET 基础类型中的值类型和引用类 ...
- C# 值类型和引用类型等值判断
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- 6个重要的.NET概念:栈,堆,值类型,引用类型,装箱,拆箱
引言 本篇文章主要介绍.NET中6个重要的概念:栈,堆,值类型,引用类型,装箱,拆箱.文章开始介绍当你声明一个变量时,编译器内部发生了什么,然后介绍两个重要的概念:栈和堆:最后介绍值类型和引用类型,并 ...
- .NET六大剑客:栈、堆、值类型、引用类型、装箱和拆箱
.NET六大剑客:栈.堆.值类型.引用类型.装箱和拆箱 一.“堆”,“栈”专区 这两个字我相信大家太熟悉了,甚至于米饭是什么?不知道...“堆”,“栈”是什么?哦,这个知道... 之前我也写过一篇堆栈 ...
- 6个重要的.NET概念: - 堆栈,堆,值类型,引用类型,装箱和拆箱(转)
今天在Code Project上面看到一篇文章<6 important .NET concepts: - Stack, heap, Value types, reference types, b ...
- [No0000136]6个重要的.NET概念:栈,堆,值类型,引用类型,装箱,拆箱
引言 本篇文章主要介绍.NET中6个重要的概念:栈,堆,值类型,引用类型,装箱,拆箱.文章开始介绍当你声明一个变量时,编译器内部发生了什么,然后介绍两个重要的概念:栈和堆:最后介绍值类型和引用类型,并 ...
- .NET面试题解析(01)-值类型与引用类型
系列文章目录地址: .NET面试题解析(00)-开篇来谈谈面试 & 系列文章索引 常见面试题目: 1. 值类型和引用类型的区别? 2. 结构和类的区别? 3. delegate是引用类型还 ...
- C# 值类型和引用类型
一.基本概念 C#只有两种数据类型:值类型和引用类型 值类型在线程栈分配空间,引用类型在托管堆分配空间 值类型转为引用类型称成为装箱,引用类型转为值类型称为拆箱 以下是值类型和引用类型对照表 从上图可 ...
- C#学习笔记之值类型与引用类型
[TOC] C#学习笔记之值类型与引用类型 1.值类型与引用类型 1.1 深层区别 值类型与引用类型有不同的内存分布,这导致了不同的内存管理机制: 值类型由OS负责内存管理 引用类型由垃圾回收器(GC ...
随机推荐
- linux下Ctrl命令组合
1.键盘组合键操作 ctrl-c 发送 SIGINT 信号给前台进程组中的所有进程.常用于终止正在运行的程序. ctrl-z 发送 SIGTSTP 信号给前台进程组中的所有进程,常用于挂起一个进程. ...
- Merkle tree在区块链中的应用
上篇博文我们转载了一篇<Merkle Tree(默克尔树)算法解析>,那么大家是不是会有疑问,学习这个算法之后,我们改怎么去应用,区块链中又是如何应用的?今天这篇博客就以Merkle tr ...
- Struts – MappingDispatchAction Example
Struts MappingDispatchAction class is used to group similar functionality into a single action class ...
- CCF CSP 201403-3 命令行选项
CCF计算机职业资格认证考试题解系列文章为meelo原创,请务必以链接形式注明本文地址 CCF CSP 201403-3 命令行选项 问题描述 请你写一个命令行分析程序,用以分析给定的命令行里包含哪些 ...
- Sample ASP.NET IHttpHandler
LoggerHandler.cs using System; using System.Collections.Generic; using System.Diagnostics; using Sys ...
- Django实战(18):提交订单
前面的内容已经基本上涵盖了Django开发的主要方面,我们从需求和界面设计出发,创建模型和修改模型,并通过scaffold作为开发的起点:在scaffold的基础上重新定制模板,并且通过Model类和 ...
- WordCount_命令行运行时指定参数
WordCountApp命令行运行时指定参数 1.修改之前的WordCountApp.java的代码 package cmd; import java.net.URI; import org.apac ...
- 链路跟踪技术traceId的总结和实践
目录 写作背景 什么是链路跟踪 目前常见的链路跟踪技术及其优缺点 链路跟踪技术的实现原理 代码示例 背景 由于最近系统上线后,访问量达,出现线上问题后往往无从下手排查,即使打印了很多日志,依然无法快速 ...
- 容易错的try
配对方式一:try{}catch{}配对方法二:try{}catch{}finally{}配对方法三:try{}finally{}所以可用看出 catch和finally都不是必须的,try和catc ...
- 怎么将maven项目打包成war包
问题:我在eclipse上能运行,然后我想将这个maven项目打包成war然后放到另外一台机子上(其实是手动放在tomcat的webapp目录中),提供外部访问.现在问题是,一直maven项目打包一直 ...