百科问答小站 logo
百科问答小站 font logo



C#中的引用类型在堆栈(内存)中是怎么工作的? 第1页

  

user avatar   Ivony 网友的相关建议: 
      

这是个字面量的问题,和引用类型几乎没什么关系。

的确就是编译器的行为,考虑一下编译器怎么处理字面量?

如果是简单的值类型,譬如说1、5、2000之类,那就直接编译成对应的代码就完了,也就是说字面量直接插在对应出现的地方。

但是对于引用类型,我们需要放一个引用在那里,因为最底层只能是加载引用到堆栈。那么我们需要先创建一个对象实例出来,然后才能得到引用。然后很自然的我们就会想到,字符串这种不可变的对象,完全没有必要对每一个字面量都创建一个新的实例,如果两个字面量是一模一样的字符串,那么我当然可以直接用同一个字符串实例就好了……


所以编译器在编译的时候,发现两个一样的字面量字符串,就会使用同一个实例……

本质上就是这么个事情。


user avatar   hex-33 网友的相关建议: 
      

其实这个牵涉到一个编译器行为的问题,因为字符串从字面量初始化是编译器内建支持并且有用CLI规定专用IL指令来实现的。所以要看最后的结果,最好是根据生成的IL指令来判断。

另外提一个点:其实字符串的intern是几乎要手动通过String.Intern操作的,实际上自动的所谓”Intern“只能存在这种编译器有优化进行字符串合并的情况下,生成了一些优化的代码,给了你一种会自动Intern的错觉。除开这个情况,String和其他引用类型的行为是没有什么差距的,直接去赋值会导致引用指向同一个对象。

例子:(Release)

第一个与第三个例子都被编译器成功识别,转换为同一个字面量的ldstr,而第二个就没那么幸运了,老老实实做了Concat最后再存储回去。第四个例子不用说,记住String不会自动Intern。




  

相关话题

  如何优化如图所示的,将父类实例扩展为子类实例的代码? 
  C++ 和 Java 同样是静态语言,为什么 Java 的代码提示可以做的十分强大? 
  C#中字符串可以使用可变大小的内存,为什么数字不能? 
  C#每个类代码一大坨,有什么好的方能展示他的公有方法和属性? 
  .NET 平台中有很多 BS 框架,能介绍一下他们之间的关系和实用价值吗? 
  C# 异步中Task.Wait的坑? C# Task.Wait为什么不等待就返回? 
  C# 从语法角度比 Java 优秀在哪里? 
  C# 和 Java 哪个更像 C++? 
  作为非计算机专业的学生,觉得 C 语言远比其他语言易于上手,正常吗? 
  这篇博文c#比JAVA慢这么多 为什么? 

前一个讨论
C++为何不允许在函数中直接传递数组?
下一个讨论
腾讯声称为保护未成年人扩大人脸识别,会侵犯其他用户隐私信息吗?





© 2024-11-16 - tinynew.org. All Rights Reserved.
© 2024-11-16 - tinynew.org. 保留所有权利