.NET 中的引用类型 string

String 在.net 2.0 中的定义为:
[SerializableAttribute]
[ComVisibleAttribute(true)]
public sealed class String : IComparable, ICloneable, IConvertible,
    IComparable<string>, IEnumerable<string>, IEnumerable IEquatable<string>

毫无疑问,string为引用类型,但在使用过程中它又表现出一些值类型的特点。
1.string 重载了 ==、!= 运算符 

// 重载 == 运算符
public static bool operator ==(String a, String b)
{
    return Equals(a, b);
}
 
// 重载 != 运算符
public static bool operator !=(String a, String b)
{
    return !Equals(a, b);
}

string 对象重写了 Equals 方法,实现字符串的比较。

2.string 是只读的。
不能修改该对象实例的值,实际操作中对该对象实例的修改返回的是该对象的新的实例。而 StringBuilder 则是在原对象实例基础上的修改,这就是修改操作时 StringBuilder 效率高于 string 对象的原因。string 对象保留在堆上,而不是堆栈上,当相同的字符串赋值到两个string变量时,会得到相同内存中的字符串的两个引用,这样做的目的是提高效率,对其进行了特殊优化,字符串是经常用的基本数据类型并且是只读类型,没有必要把相同的字符串在内存中保留多个复本。

//
相同的字符串赋值到两个 string 变量时,会得到相同对内存中的字符串的两个引用
string aa = "hello";
string bb = "hello";
Console .Write(string.Equals(aa, bb)); //true
Console .Write(string.ReferenceEquals(aa, bb)); //true
 
// 改变字符串,获得新的实例
bb += "o";
Console .Write(string.Equals(aa, bb)); //false
Console .Write(string.ReferenceEquals(aa, bb)); //false

3.参数传递中的假象 
疑问:当字符串变量作为参数传递时并未改变它的值。

string
str = "hello";
Console .WriteLine(str); //hello
Console .WriteLine(ChangeString(str)); //helloo
Console .WriteLine(str); //hello
 
Console .WriteLine(string.Equals(str, str)); //true
Console .WriteLine(string.Equals(str, ChangeString(str))); //false
 
// 改变字符串
private string ChangeString(string str)
{
    str += "o";
 
    return str;
}

原因是字符串是只读的,改变时创建了一个新的对象。这时应该明确的标识 ref 或 out。
这不是个别现象,引用类型作为参数传递欲改变对象本身时都应明确的标识 ref 或 out,这让我想起当初学C语言是指针作为参数传递时为什么没有改变原指针本身:应该传递的是指针的地址。
下面的代码举例比较明显:

// 测试
Test1 tst = new Test1();
tst.aa = 1;
 
ChangeClass(tst);
Console .WriteLine(tst.aa); //1
 
ChangeClassRef(ref tst);   
Console .WriteLine(tst.aa); //3
 
// 测试值传递参数
public void ChangeClass(Test1 tst)
{
    tst = new Test1();
    tst.aa = 2;
}
 
// 测试引用传递参数
public void ChangeClassRef(ref Test1 tst)
{
    tst = new Test1();
    tst.aa = 3;
}
 
// 测试用类
public class Test1
{
    public int aa = 0;
}

你可能感兴趣的:(String)