官术网_书友最值得收藏!

2.8.5 字符串的隱藏問(wèn)題

字符串隱藏問(wèn)題涉及ToCharArray、Clone、Compare等內(nèi)容。其中,string.ToCharArray返回的char[]數(shù)組是一個(gè)新創(chuàng)建的字符串?dāng)?shù)組,與原string無(wú)關(guān),我們修改返回的字符串中的數(shù)據(jù)不會(huì)影響原來(lái)的string對(duì)象。至于string.Clone、string.ToString()接口,它們并不會(huì)重新構(gòu)建一個(gè)string,而是會(huì)直接返回當(dāng)前的string對(duì)象,如果想要?jiǎng)?chuàng)建一個(gè)一模一樣的string,需要我們自行新建一個(gè)string對(duì)象并傳入原字符串。

字符串比較也會(huì)有隱藏問(wèn)題,當(dāng)兩個(gè)字符串比較時(shí),string會(huì)先比較兩個(gè)字符串的指針是否一致,一致則返回true,如果指針不一致,則會(huì)遍歷兩者,并判斷每個(gè)字符是否相等。我們來(lái)看看它究竟是怎么做的,源碼如下:


public bool Equals(String value) {
    if (this == null)                           // 這對(duì)于防止反向pinvokes和其他不使用
        throw new NullReferenceException();     // callvirt指令的調(diào)用者是必要的

    if (value == null)
        return false;

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

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

    return EqualsHelper(this, value);           // 遍歷兩者的字符
}

以上代碼是先判定兩個(gè)string的引用是否相等,如果不相等,再判斷兩者的長(zhǎng)度是否相等,如果長(zhǎng)度相等,再遍歷字符串的每個(gè)字符,判斷每個(gè)字符是否相等,最終判定字符串是否相等。

若操作的兩個(gè)字符串來(lái)自不同的內(nèi)存段,那么在比較它們是否相等時(shí)就會(huì)遍歷所有字符來(lái)判定是否相等,偽代碼如下:


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;

這段代碼最終會(huì)返回false,strA與strB看似相等,實(shí)則為不同內(nèi)存段的內(nèi)容,當(dāng)它們使用等號(hào)比較時(shí),就會(huì)遍歷所有字符串里的字符來(lái)確定它們是否相等。

string源碼地址為https://referencesource.microsoft.com/#mscorlib/system/string.cs

主站蜘蛛池模板: 呼和浩特市| 河北区| 石景山区| 荣昌县| 怀集县| 普兰县| 台东市| 毕节市| 长岛县| 泗阳县| 青龙| 多伦县| 江门市| 房产| 安顺市| 呼玛县| 舟曲县| 温泉县| 中卫市| 西峡县| 咸宁市| 丰原市| 泾源县| 双鸭山市| 甘德县| 高青县| 淅川县| 同心县| 遵义县| 寿宁县| 邳州市| 新疆| 霍州市| 郸城县| 西盟| 康保县| 永和县| 通州区| 贞丰县| 平阴县| 东辽县|