字符串是值类型还是引用类型?

时间:2009-07-01 13:30:26

标签: .net string reference types

字符串是值类型还是引用类型?

我找不到这个“好”的解释...

8 个答案:

答案 0 :(得分:91)

Console.WriteLine(typeof(string).IsClass); // true

这是一种参考类型。

它不能是值类型,因为值类型需要已知的堆栈大小等。作为参考类型,引用的大小是事先已知的,甚至如果字符串的大小不是。

行为就像你期望一个值类型行为一样,因为它是不可变的;即它一旦创建就不会改变。但是还有很多其他不可变的引用类型。例如,委托实例。

* =除了StringBuilder内部,但在执行此操作时你永远不会看到它......

答案 1 :(得分:17)

String是一个不可变的引用类型。

有关不变性的信息,请参阅博客文章 Immutable types: understand their benefits and use them

答案 2 :(得分:13)

答案 3 :(得分:11)

基本的“解释”基于“什么”实际存储在您为事物“声明”变量时分配的内存位置。如果事物的实际值存储在变量名称引用的内存位置,则它是值类型。

   int x;  // memory allocated to hold Value of x, default value assigned of zero

如果,otoh,当您“声明”变量时分配的内存插槽将只保存一些其他内存地址,其中将存储实际值(或值),那么它是一个引用类型

   MyClass x;  // Memory allocated to hold an address, 
               // default address of null (0) assigned.  
               // NO MEMORY ALLOCATED for x itself 

或者,如果声明包括初始化,

   MyClass x = new MyClass();  
     // Now, Memory slot (call it Addr1) is allocated to hold address of x, 
     // more memory (call it Addr2) is allocated to hold a new MyClass object.
     // New MyClass object created, stored in memory Addr2 (on the Heap)
     // Address of new object (Addr2) is stored in Addr1

对于一个字符串,该字符串是在Heap上创建的,它的地址位于为该变量分配的内存槽中,因此它是一个引用类型。

答案 4 :(得分:5)

String是一种不可变的引用类型,它具有某些特性,偶尔会出现一种值类型

答案 5 :(得分:4)

字符串类型表示零个或多个Unicode字符的序列。 string是.NET Framework中String的别名。

虽然string是引用类型,但是定义了相等运算符(==和!=)来比较字符串对象的值,而不是引用。这使得对字符串相等性的测试更加直观。例如:

string a = "hello";
string b = "h";
// Append to contents of 'b'
b += "ello";
Console.WriteLine(a == b);
Console.WriteLine((object)a == (object)b);

这显示“True”然后显示“False”,因为字符串的内容是等效的,但a和b不引用相同的字符串实例。

字符串是不可变的 - 创建对象后无法更改字符串对象的内容,尽管语法使其看起来好像可以执行此操作。例如,当您编写此代码时,编译器实际上会创建一个新的字符串对象来保存新的字符序列,并将该新对象分配给b。然后字符串“h”有资格进行垃圾收集。

string b = "h";
b += "ello";

答案 6 :(得分:3)

在许多语言中,有两种常见类型的东西:定义类型的存储位置实际上将保存该类型的对象的那些,以及定义类型的存储位置将保存对象的引用的那些类型那种存储在别处的那种事物可能提供了许多类型的语义:

  1. 不可变值语义:特定类型的实例具有形成身份基础的某些特征(“值”)。值相等的两个项目可以互换使用,无论它们存储在何处。只要实例存在,该值将保持不变。这种类型的变量可能会更改其值,但只能通过将不同的实例存储到变量中。
  2. 不可变引用语义:通常类似于不可变值语义,除了在不同时间创建的两个实例将自己报告为不同的实例。
  3. 可变值语义:特定类型的实例具有构成身份基础的某些特征或特征集合(“值”),但可以在不替换整个实例的情况下更改这些特征。每个实例都存储在一个变量或字段中;将一个变量或字段复制到另一个变量或字段会将所有值从第一个实例复制到第二个实例,但实例保持独立。对一个实例的未来更改不会影响另一个实例。
  4. 可变引用语义:每个实例都与自身相同,但不与其他实体相同,并且实例具有一个或多个可在现有实例中更改的值。任意数量的变量或字段都可以包含对任何实例的引用。将一个或一个字段变量复制到另一个只是使第二个引用与第一个相同的实例。因此,对其中一个变量引用的实例的任何更改都将影响另一个变量引用的实例(即同一实例)。

在某些编程语言(如C ++)中,直接存储和间接引用类型都可以实现上述四种语义中的任何一种。在.net和C#中,具有公开字段的直接存储类型总是实现#3,具有公开字段的类类型总是实现#4,其他值类型可以实现上述任何一种,其他引用类型可以实现#1,#2,或#4,但不是#3,抽象只有轻微的漏洞。字符串实现#1。

答案 7 :(得分:2)

也许文章 Strings in .NET and C# 可以为您提供帮助。根据这篇文章,string是一个引用类型。

相关问题