为什么System.Int32是结构体而System.String是类?

10

自从我开始学习 c# 编程以来,这个问题一直在我的脑海中浮现:

为什么 int 是一个 struct 类型?

图片描述

string 是一个 class 类型?

图片描述


2
首先,请阅读structclass之间的区别。其次,因为int32位,非常适合于struct。但是你无法知道string可以有多大。 - Soner Gönül
2个回答

11
因为int是固定长度的,而string长度可变。因此,编译器可以为int保留一个固定的区域(主要在堆栈上),而必须在堆上维护一个string的可变长字符数组缓冲区。

如果 String 包含一个 Char[] 类型的字段,它本身就可以是一个值类型。这样的设计优点在于允许 default(String) 行为类似于空字符串 [就像之前的 COM 框架],而不是 null 值;但缺点在于每当将字符串转换为 Object 时都需要进行装箱。 - supercat

4

int是一个值类型,而string是一个引用类型。当你将值类型传递给方法或将其分配给新变量等时,值类型会通过值(复制)传递。引用类型只有引用被复制。

对于像int或float这样的小对象来说,复制是快速的,但在某些情况下,复制操作的成本变得昂贵,因此引用比一直复制值更可取。

虽然字符串也是不可变的,像大多数值类型一样(是否存在可变值类型?),但由于字符串可能非常大,因此它们不适合通过值传递。


1
并非完全正确。由于字符串的长度具有固有的动态性,编译器无法为字符串分配固定大小的内存块。 - Thomas Weller
1
是的,可以有可变值类型(您可以定义自己的结构体),但不,这不是一个好主意。 - Hans Kesting
1
@ThomasWeller:String 可以被定义为一个结构体,其中包含一个私有字段,它持有一个指向某个可变大小对象(例如 Char[])的引用,该对象永远不会被修改。这样的设计将使得 default(String) 表现为一个空字符串而不是一个空值,这可能会减轻为 COM 编写的代码的移植,因为 COM 将所有位为零的指针视为空字符串的合法表示。然而,将这样的字符串转换为 Object 需要进行装箱或特殊的框架“魔法”来避免装箱。 - supercat

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接