1.String分配了之后就无法更改?
下面的代码会造成编译错误:
string
s
=
"
hello
"
;
s[
0
]
=
'
a
'
;
会造成:
Error 3 Property or indexer 'string.this[int]' cannot be assigned to -- it is read only
事实上是可以改变的:
unsafe
{
string
s
=
"
hello
"
;
fixed
(
char
*
p1
=
s)
{
*
p1
=
'
a
'
;
}
}
2.String不能用new来构造?
由于代码
string
s
=
new
string
(
"
hello
"
);
会报错,没有此类ctor但是实际上string有8个ctor:
public
String(
char
*
value);
public
String(
char
[] value);
public
String(
sbyte
*
value);
public
String(
char
c,
int
count);
public
String(
char
*
value,
int
startIndex,
int
length);
public
String(
char
[] value,
int
startIndex,
int
length);
public
String(
sbyte
*
value,
int
startIndex,
int
length);
public
String(
sbyte
*
value,
int
startIndex,
int
length, Encoding enc);
3.字符串“+”会生成新的字符串?
string
s
=
"
he
"
+
"
ll
"
+
"
o
"
;
看看IL:
IL_0000:
nop
IL_0001:
ldstr
"
hello
"
IL_0006:
stloc.0
IL_0007:
ret
事实上是一个字符串,编译器做了我们不知道的事情。
4.StringBuilder为什么会比String性能好?
String s
=
null
;
for
(
int
i
=
0
; i
<
100
; i
++
)
s
+=
i.ToString();
+实际调用的是String的静态方法public static string Concat(string str0, string str1)
public
static
string
Concat(
string
str0,
string
str1)
{
if
(IsNullOrEmpty(str0))
{
if
(IsNullOrEmpty(str1))
{
return
Empty;
}
return
str1;
}
if
(IsNullOrEmpty(str1))
{
return
str0;
}
int
length
=
str0.Length;
string
dest
=
FastAllocateString(length
+
str1.Length);
FillStringChecked(dest,
0
, str0);
FillStringChecked(dest, length, str1);
return
dest;
}
下面的代码:
StringBuilder sb
=
new
StringBuilder();
for
(
int
i
=
0
; i
<
100
; i
++
)
sb.Append(i.ToString());
Append(String)方法:
public
StringBuilder Append(
string
value)
{
if
(value
!=
null
)
{
string
stringValue
=
this
.m_StringValue;
IntPtr currentThread
=
Thread.InternalGetCurrentThread();
if
(
this
.m_currentThread
!=
currentThread)
{
stringValue
=
string
.GetStringForStringBuilder(stringValue, stringValue.Capacity);
}
int
length
=
stringValue.Length;
int
requiredLength
=
length
+
value.Length;
if
(
this
.NeedsAllocation(stringValue, requiredLength))
{
string
newString
=
this
.GetNewString(stringValue, requiredLength);
newString.AppendInPlace(value, length);
this
.ReplaceString(currentThread, newString);
}
else
{
stringValue.AppendInPlace(value, length);
this
.ReplaceString(currentThread, stringValue);
}
}
return
this
;
}
通过比较:
string是每次拼接后都需要分配空间,并返回新string的引用。而StringBulder则是预分配空间,而当字符串拼接时,则先检查字符串的空间,再决定是否需要分配新空间。向堆上申请内存空间是比较耗时的操作。