字符串特性
定义
字符串(string)实际上就是字符的几何(char[]),其作为基元类型,对应System.String,其类型定义如下:
public sealed class String : IComparable, ICloneable, IConvertible, IComparable<String>,
IEnumerable<char>, IEnumerable, IEquatable<String>
由此可见字符串是一个类结构,而不是结构体,说明字符串是引用类型,同时也可以通过字符串默认值为null这一点可以看出,字符串是一个引用类型,所以针对字符串的操作会牵扯到堆上的内存分配活动
在我们使用的过程中,往往字符串的使用方式与值类型像是,然而字符串被微软设计为一个密封类(且具有不变性),是基于一下的原因:
- 一个线程栈的大小只有1MB空间,其他值类型的长度是固定,但是字符串的长度是不定的,可能是十分巨大的
- 字符串如果被设计为值类型,则方法传入字符串将会拷贝其值而不是引用,如果字符串长度巨大,则会影响性能
- 不变性使得字符串是线程安全的
- 字符串驻留节省内存,而它只能借助不可变性来实现
字符串与普通引用类型的比较
字符串的使用方式与值类型很相似:
- 字符串通过"=="进行互相比较,且比较的是字符串的值,而不是其是否指向同一个堆上的地址
- 字符串被传入另一方法后,在另一方法内部进行修改,执行完毕之后,外部字符串的值不会被改变
对于第一点的实现,字符串的**"==“与”!="操作符以及Equals**方法被重写为比较字符串的值而不是引用
字符串的不变性
什么是字符串的不变性
一般情况下,我们将“一经赋值,其值就不能被更改”视为不变性,字符串的不变性就是指,字符串一经赋值,其值就不能被更改,当通过代码使字符串变量等于一个新的值的时候,堆上会出现一个新的字符串,然后,栈上的变量指向新的字符串,没有办法更改原来字符串的值,可参考下图进行理解
同样我们还可以通过C#代码来验证字符串的不变性
static void ProveImmutable()
{
string a = "a";
string b = a;
// true
Console.WriteLine(ReferenceEquals(a, b));
b = "2";
// false
Console.WriteLine(ReferenceEquals(a, b));
}
同时我们可以查看System.String类型的成员来证明其不变性
字段类型中除了若干常量之外就剩下内容:
- 一个readonly的Empty,值为空
- 私有的m_stringLength,无法被外界更改
属性有: - Chars[Int32],代表字符串成员
- Length,代表字符串长度
public static readonly String Empty;
public char this[int index] {
get; }
public int Length {