上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。