由于C#中可以使用以下代码,因此我认为string是否实际上是一个字符数组:
string a="TEST";
char C=a[0]; // will be T
答案 0 :(得分:18)
System.String不是Char的.NET数组,因为:
char[] testArray = "test".ToCharArray();
testArray[0] = 'T';
会编译,但是这个:
string testString = "test";
testString[0] = 'T';
不会。字符串数组是可变的,字符串不是。此外,string is Array
返回false,而char[] is Array
返回true。
答案 1 :(得分:14)
不,这不是阵列。但它确实有一个索引器。两全其美。
答案 2 :(得分:5)
.NET中的字符串由System.String
类支持,该类在内部使用一堆不安全的方法,使用标准的C内存操作技术对实际的字符串数据进行指针操作。
String
类本身不包含数组,但它有一个索引器属性,允许您将数据视为数组。
答案 3 :(得分:3)
不,String是.Net中的一个类。它可能由数组支持。但它不是一个数组。类可以有索引器,这就是String正在做的事情。
请参阅有关此声明的详细说明:根据我的理解,所有字符串都存储在一个公共blob中。因此,“foo”和“foo”指向该blob中的相同点...字符串在C#中不可变的原因之一。
答案 4 :(得分:2)
string
不是char[]
,但确实有.ToCharArray()
。它还有一个索引器,它允许你单独访问字符,就像你已经显示的那样。它可能是在内部使用数组实现的,但这是一个实现细节。
答案 5 :(得分:2)
一个字符串对象包含一个连续的characers块,就像一个字符数组,但字符串对象既不是,也不包含数组对象。
编译器知道字符串字符串是不可变的,因此当您访问字符串时它可以进行某些优化,其方式与访问数组时的优化方式相同。因此,当您通过索引访问字符串时,代码可能最终直接访问字符串数据而不是调用索引器属性。
答案 6 :(得分:2)
为斯科特·多尔曼和古法的回答添加一些内容。如果你在字符串'abcd'上使用Windbg和!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 <<
你会发现它只有三个实例字段。 m_arrayLength,m_stringLength和m_firstChar。它不包含实例System.Char []其他2个字段是静态共享的,因此每个System.String都具有相同的空字符串和WhitespaceChar字符数组。
如果您使用DumpByte,您将看到堆中的字符串数据(在本例中为abcd),当然从偏移量0x0c(m_firstChar)开始,宽度为8字节(对于unicode,m_stringLength为4 x 2) 。
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读取数据。
答案 7 :(得分:2)
String是一个类,它接受一个char数组来自己初始化,所以当你尝试在某个索引处获取元素时,它返回char。 检查字符串类
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>
继承。
在字符串类中有一个get属性,它在传递索引时返回char,请参阅图像。这清楚地说明了在当前System.String
中的指定位置获取System.Char对象public char this[int index] { get; }
答案 8 :(得分:1)
string
不是char
的数组,除非您将其转换为1。该表示法仅用于访问字符串中不同位置(索引)的字符。
答案 9 :(得分:1)
使用Reflector,我们可以看到该字符串确实实现了IEnumerable<char>
。所以,它不是一个字符数组,但实质上可以像一个一样使用。
public sealed class String : IComparable, ICloneable, IConvertible, IComparable<string>, IEnumerable<char>, IEnumerable, IEquatable<string>
修改强>
实施IEnumerable<char>
并不意味着该类型将被编入索引。我不是故意转达那个。这意味着您可以枚举它并像集合一样使用它。我想说的更好的方法是字符串不是字符数组,而是字符集合。感谢您的评论。
答案 10 :(得分:1)
在"Hello" is char[]
评估为false
的意义上,字符串不是数组。
答案 11 :(得分:0)
每个人都给出了一半答案,所以这两部分都是:
1)严格来说,是的,.NET中的String是一个字符数组。它的内部实现和数组的语义定义都是如此。
2)然而,正如其他人所指出的那样,字符串有点奇怪。它不是所有其他数组的System.Array。因此,在严格的.NET特定方式中,String不是数组。