幾天前的一次筆試中遇到了關於StringBuilder的Length和Capacity屬性的問題,之前忽略了。今天實踐下:
1.普通實踐
官方解釋如下:
StringBuilder.Capacity:獲取或設置可包含在當前實例所分配的內存中的最大字符數。
StringBuilder.Length:獲取或設置當前 StringBuilder 對象的長度。
class Program { static void Main(string[] args) { StringBuilder sb = new StringBuilder("0123456789");//長度為10 Console.WriteLine("sb.Length:" + sb.Length + " sb.Capacity:" + sb.Capacity); Console.ReadKey(); } }
輸出結果為:10 16
這里可以說明StringBuilder的Capacity最小分配的長度是16.當初始化一個長度為17的字符串時,如StringBuilder sb = new StringBuilder("01234567891234567"),
顯示的是17。
2.文藝實踐
在代碼里面更改Length的值,這時在看看它們的值各是多少。代碼如下:
class Program { static void Main(string[] args) { StringBuilder sb = new StringBuilder("0123456789");//10 sb.Length = 6; sb.Append("012345678");//9 Console.WriteLine("sb.Length:" + sb.Length + " sb.Capacity:" + sb.Capacity+" "+sb.ToString()); Console.ReadKey(); } }
輸出結果為:
可以知道:當我們顯示的更改了Length的值以后,字符串前面的部分保留,后面的丟棄了。最終的Length值為15,這時仍然小於16,所以Capacity為16。更改下代碼:
sb.Append("012345678910");在前面的基礎上增加這里的長度到12位。這時輸出結果為:Length為18,Capacity為32。說明Capacity是以16的倍數增長。
如果顯示的更改Capacity的值會怎么樣?
class Program { static void Main(string[] args) { StringBuilder sb = new StringBuilder("0123456789");//10 sb.Length = 6; sb.Capacity=15; sb.Append("012345678910");//長度12 Console.WriteLine("sb.Length:" + sb.Length + " sb.Capacity:" + sb.Capacity+" "+sb.ToString()); Console.ReadKey(); } }
這時輸出18,30.因為18超出了這里已經指定的Capacity的值15,成倍增長到30. 所以Capacity增長的基數默認是16,如果有顯示指定,則為指定的值。
接着修改下代碼,sb.Capacity=8。這樣Capacity的2倍都比Length小,這時輸出的結果為:18,18. 這里並不是在Capacity的初值8的基礎上成倍增加。
3.2B實踐
其實從上面的實踐可以看出,Capacity的大小分配是在滿足Length的情況下,盡量少占用空間。跟Length和顯示指定的Capacity大小有關系。
class Program { static void Main(string[] args) { StringBuilder sb = new StringBuilder("0123456789");//10 sb.Length = 6; sb.Capacity=5; sb.Append("012345678910");//長度12 Console.WriteLine("sb.Length:" + sb.Length + " sb.Capacity:" + sb.Capacity+" "+sb.ToString()); Console.ReadKey(); } }
當Capacity小於Length時,會拋出異常System.ArgumentOutOfRangeException.