string a="TEST";
char C=a[0]; // will be T
System.String 不是 .NET 字符数组,因为它具有以下特点:
char[] testArray = "test".ToCharArray();
testArray[0] = 'T';
能编译通过,但是这个:
string testString = "test";
testString[0] = 'T';
不会。字符数组是可变的,而字符串不可变。另外,string is Array
返回false,而 char[] is Array
返回true。
.NET中的字符串由System.String
类支持,该类在内部使用一些不安全的方法,使用标准的C内存操作技术对实际字符串数据进行指针操作。
String
类本身不包含数组,但它具有索引器属性,允许您将数据视为数组。
补充一下 Scott Dorman 和 Gufa 的回答。如果您使用 Windbg 并在字符串 abcd
上使用 !DumpObject
,你会得到类似于这样的结果。
0:000> !do 01139b24
Name: System.String
MethodTable: 79330a00
EEClass: 790ed64c
Size: 26(0x1a) bytes
(C:\WINDOWS\assembly\GAC_32\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll)
String: abcd
Fields:
MT Field Offset Type VT Attr Value Name
79332c4c 4000096 4 System.Int32 1 instance 5 m_arrayLength
79332c4c 4000097 8 System.Int32 1 instance 4 m_stringLength
793316e0 4000098 c System.Char 1 instance 61 m_firstChar
79330a00 4000099 10 System.String 0 shared static Empty
>> Domain:Value 00181b38:01131198 <<
79331630 400009a 14 System.Char[] 0 shared static WhitespaceChars
>> Domain:Value 00181b38:011318b8 <<
0:000> db 01139b24 L1A
01139b24 00 0a 33 79 05 00 00 00-04 00 00 00 61 00 62 00 ..3y........a.b.
01139b34 63 00 64 00 00 00 00 00-00 00 c.d......
如果你查看SSCLI,你会发现它(就像Scott所说的)要么运行不安全的代码,使用指针技术来读取数据,使用m_firstChar
和m_stringLength
。
String是一个类,它需要一个char数组来初始化自己,因此当你尝试获取某个索引处的元素时,它会返回char类型。
请查看String类。
public sealed class String : IComparable, ICloneable, IConvertible, IComparable<string>, IEnumerable<char>, IEnumerable, IEquatable<string>
{
// Summary:
// Initializes a new instance of the System.String class to the value indicated
// by an array of Unicode characters.
//
// Parameters:
// value:
// An array of Unicode characters.
[SecuritySafeCritical]
public String(char[] value);
}
另请参见String类声明。
public sealed class String : IComparable, ICloneable, IConvertible, IComparable<string>, IEnumerable<char>, IEnumerable, IEquatable<string>
这被IEnumerable<char>
继承了。
在string类中有一个获取属性,当传递索引时返回char,如下图所示。它清楚地说明:获取当前System.String中指定位置的System.Char对象
public char this[int index] { get; }
string
并不是char[]
,虽然它确实有一个.ToCharArray()
方法。同时,它也有一个索引器,允许您像您展示的那样单独访问字符。很可能它在内部使用了一个数组来实现,但这是实现细节。
不,String是.NET中的一个类。它可能由数组支持,但它本身不是数组。类可以有索引器,而这就是String所做的事情。
有关此声明的详细说明,请参见注释:据我所知,所有字符串都存储在一个常用的blob中。由于这个原因,“foo”和“foo”指向该blob中的同一点……这也是C#中字符串不可变的原因之一。
一个字符串对象包含一段连续的字符块,就像一个字符数组,但是字符串对象既不是也不包含一个数组对象。
编译器知道字符串是不可变的,因此当您访问字符串时,它可以进行某些优化,就像在访问数组时进行优化一样。因此,当您通过索引访问字符串时,代码很可能直接访问字符串数据而不是调用索引器属性。
字符串不是一个数组,这意味着 "Hello" 是 char[]
的判断结果为 false
。
string
直到你将其转换为数组 char
,它才不是一个数组。这种表示法仅用于访问字符串中不同位置(索引)的字符。