Unity3D高级编程:主程手记
上QQ阅读APP看书,第一时间看更新

2.8.5 字符串的隐藏问题

字符串隐藏问题涉及ToCharArray、Clone、Compare等内容。其中,string.ToCharArray返回的char[]数组是一个新创建的字符串数组,与原string无关,我们修改返回的字符串中的数据不会影响原来的string对象。至于string.Clone、string.ToString()接口,它们并不会重新构建一个string,而是会直接返回当前的string对象,如果想要创建一个一模一样的string,需要我们自行新建一个string对象并传入原字符串。

字符串比较也会有隐藏问题,当两个字符串比较时,string会先比较两个字符串的指针是否一致,一致则返回true,如果指针不一致,则会遍历两者,并判断每个字符是否相等。我们来看看它究竟是怎么做的,源码如下:


public bool Equals(String value) {
    if (this == null)                           // 这对于防止反向pinvokes和其他不使用
        throw new NullReferenceException();     // callvirt指令的调用者是必要的

    if (value == null)
        return false;

    if (Object.ReferenceEquals(this, value))
        return true;

    if (this.Length != value.Length)
        return false;

    return EqualsHelper(this, value);           // 遍历两者的字符
}

以上代码是先判定两个string的引用是否相等,如果不相等,再判断两者的长度是否相等,如果长度相等,再遍历字符串的每个字符,判断每个字符是否相等,最终判定字符串是否相等。

若操作的两个字符串来自不同的内存段,那么在比较它们是否相等时就会遍历所有字符来判定是否相等,伪代码如下:


string strA = "Hello ";

string strB = "Hello ";

strA = strA + "C";

strB = strB + "C";

if(Object.ReferenceEquals(strA, strB))
{
    return true;
}

if(strA == strB)
{
    return false;
}

return true;

这段代码最终会返回false,strA与strB看似相等,实则为不同内存段的内容,当它们使用等号比较时,就会遍历所有字符串里的字符来确定它们是否相等。

string源码地址为https://referencesource.microsoft.com/#mscorlib/system/string.cs