C#中关于字符串的一些特殊点

在C#中,字符串是一个使用比较多的类型,本文会讲到字符串(string)的一些特殊点。

定义

我们先来定义一个字符串类型变量。

string str = "这是一个字符串";

在上面的代码中,我们试用了 stirng 关键字作为类型来定义字符串变量,其实字符串真正的类型为 Stringstring 是作为C#关键字的一个别名,在编码的时候,IDE会给提示,要求我们将 String 修改成 string

我们可以通过反编译来查看 String 的具体定义, String 其实是一个引用类型,派生于 Object 。但是我们在使用的过程中, String 又会表现出值类型的特性(多个变量即使指向了同一个值,在对其中一个变量修改时也不会污染到其他的变量)

public sealed class String : IComparable, ICloneable, IConvertible, IEnumerable, IComparable<string>, IEnumerable<char>, IEquatable<string>
{
}

可以看到 String 类型的定义使用 sealed 关键字,表明 String 类型不可被当作基类继承。 这是因为CLRString 类型做了一些特殊优化,必须防止自定义类型破坏了 CLR 的优化。

这里涉及到 String 类型的一个特性——不变性,即 String 对象一旦创建,就不能再更改.。不变性带来了另一个特性——一致性,即相同的字符串在 CLR 中在表现上同一个对象(其实不是)。这样在使用上, String 类型就和其他的值类型表现一致。不过由于这些特性的存在,所在如果对字符串进行多次修改操作会产生很多临时字符串对象,对性能有影响,所以在很多的库和最佳实践中,都会推荐使用 StringBuilder 来操作。

string str1 = "这是一个字符串";
string str2 = "这是一个字符串";

Console.WriteLine(object.Equals(str1,str2));
// True
Console.WriteLine(object.ReferenceEquals(str1,str2));
// False

可以看到在对象的层面上,两个字符串对象是一致的,这是因为 Equals 比较是靠 GethashCode 方法,而由于 CLR 的特殊优化, String 类型的 GetHashCode 方法会对同样的字符返回一样的哈希值。但是如果我们使用 ReferenceEquals 来比较两个对象的引用还是可以看到其实是两个对象,那么有没有办法做到字符串对象的复用呢?

答案是肯定的,我们只需要使用 Intern 方法即可。

CLR 初始化的时候,会构建一个内部表(暂存池)用来存放 String 对象的引用,而 Intern 方法就是用来访问内部表的,使用 Intern 方法的时候,会先检查内部表中有没有同样的字符串存在,如果有就会直接返回该字符串的引用。所以使用 Intern 方法获得的 String 对象在引用上也是相同的。

string str1 = "这是一个字符串";
string str2 = string.Intern("这是一个字符串");

Console.WriteLine(object.Equals(str1,str2));
// True
Console.WriteLine(object.ReferenceEquals(str1,str2));
// True

当然上面的测试都是在 .net 6的环境中进行的,如果 CLR 的实现不同,对于字符串的优化也有可能不同,甚至在 CLR 中默认开启字符串池,直接把相同值得字符串对象彻底优化成一个引用也是可能的。

发布时间:2024-08-09
其他阅读

GUID和UUID

GUID,英文全称为 Global Unique Identifier,意为全局唯一标识符,UUID,英文全称为 Universally Unique Identifier,意为通用唯一标识符,都具有唯一性,GUID也是微软对UUID是的实现。

查看原文

WPF中CornerRadius是什么属性

在WPF中,CornerRadius 属性我们经常需要使用到,它的作用是用来设置控件的四个圆角,在 BorderButton 等控件中使用。等同于 css 中的 border-radius 设置。

查看原文

IIS 设置跨域问题

之前说过nginx设置跨域,今天记录以下IIS设置跨域

查看原文

Js文件上传

文件上传是一个前端比较常见的功能,无论是以前的MVC客户端,还是现代化SPA客户端中,但万变不离其宗,其内核基本不变,本文就此讨论简单文件上传(以图片为例子)。

查看原文

JSON是什么

在现代化 Web 应用开发中,广泛使用一种名为 JSON 的数据交换格式。JSON 是一种轻量级数据交换格式,在不同系统之间提供标准且高效的数据交换。

查看原文