有时候我们需要对字符串进行修改,但是.net里面的字符串是只读的,修改动作会产生一个新的字符串,多数时候这都不是我想要的结果。不过fixed还是可以帮我们解决一部分问题的,比如.ToLower、.ToUpper、.Replace(char, char)等等,不过有个限制,就是变换前后的字符串长度不变。
public unsafe static string toLower(this string value) { if (value != null) { fixed (char* valueFixed = value) toLowerUnsafe(valueFixed, valueFixed + value.Length); } return value; } public unsafe static void toLower(char* start, char* end) { if (start != null && end > start) toLowerUnsafe(start, end); } public unsafe static void toLowerUnsafe(char* start, char* end) { while (start != end) { if ((uint)(*start - 'A') < 26) *start |= (char)0x20; ++start; } }
public unsafe static string toUpper(this string value) { if (value != null) { fixed (char* valueFixed = value) toUpperUnsafe(valueFixed, valueFixed + value.Length); } return value; } public unsafe static void toUpper(char* start, char* end) { if (start != null && end > start) toUpperUnsafe(start, end); } public unsafe static void toUpperUnsafe(char* start, char* end) { while (start != end) { if ((uint)(*start - 'a') < 26) *start -= (char)0x20; ++start; } }
public static string replace(this string value, char oldChar, char newChar) { return value != null && value.Length != 0 ? replaceUnsafe(value, oldChar, newChar) : null; } public unsafe static string replaceNotNull(this string value, char oldChar, char newChar) { return value.Length != 0 ? replaceUnsafe(value, oldChar, newChar) : value; } public unsafe static string replaceUnsafe(this string value, char oldChar, char newChar) { fixed (char* valueFixed = value) { char* start=valueFixed, end = valueFixed + value.Length; char endValue = *--end; *end = oldChar; do { while (*start != oldChar) ++start; *start = newChar; } while (start++ != end); if (endValue != oldChar) *end = endValue; } return value; }
Release实测,效果还不错,英文大小写转换运行时间降到了.ToLower与.ToUpper的1/4以下,字符替换运行时间降到了.Replace(char, char)的1/5以下,同时给垃圾回收也减少了很多压力。当然.ToLower与.ToUpper还是比较强大的,它不仅仅只是英文转换,但是我个人只处理过英文大小写问题。
需要注意的是,这里是直接修改字符串的数据,会影响到所有相关引用,如果对影响程度没有把握,一般建议应用在一次性的临时变量上。这里只是举几个例子,具体其它可能的字符串修改应用就需要你自己却发掘了。