As the following code is possible in C#, I am intersted whether string is actually an array of chars:
string a=\"TEST\";
char C=a[0]; // will be T
No, String is a class in .Net. It may be backed by an array. but it is not an array. Classes can have indexers, and that is what String is doing.
See comments for elaboration on this statement: From what I understand, all strings are stored in a common blob. Because of this, "foo" and "foo" point to the same point in that blob... one of the reasons strings are immutable in C#.
A string
is not a char[]
, although it does have a .ToCharArray()
. Also it does have an indexer, which allows you to access characters individually, like you've shown. It is likely that it was implemented with an array internally, but that's an implementation detail.
Everyone has given half the answer, so here is both parts:
1) Strictly speaking, yes, a String in .NET is an array of characters. It is so both in its internal implementation, and by the symantic definition of an array.
2) However String is, as others have pointed out, somewhat peculiar. It is not a System.Array as all other arrays are. So in the strict, .NET specific way, a String is not an Array.
Strings is simply not an array, in the sense that "Hello" is char[]
is evaluated to false
.
To add a little to Scott Dorman's and Gufa's answer. If you use Windbg and !DumpObject on the string 'abcd' you'll get somthing like this.
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 <<
You'll notice its only got three instance fields. m_arrayLength, m_stringLength and m_firstChar. It does not contain an instance System.Char[] The other 2 fields are static shared so every System.String has the same Empty string and WhitespaceChar Char Array.
If you follow that with a DumpByte you'll see the string data (in this case abcd) that's in the heap which of course starts at offset 0x0c (m_firstChar) and is 8 bytes wide (m_stringLength 4 x 2 for unicode).
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......
If you were to look in the SSCLI you'll see that it, as Scott says, either runs unsafe code and uses pointer techniques to read the data using the m_firstChar and the m_stringLength.
String is a class which takes an array of char to initialized itself, So when you try to fetch the element at some index it returns char. Check the string class
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);
}
Also see String class declaration.
public sealed class String : IComparable, ICloneable, IConvertible, IComparable<string>, IEnumerable<char>, IEnumerable, IEquatable<string>
Which is inherited by IEnumerable<char>
.
Inside the string class there is a get property which returns the char when index is passed, see the image. Which clearly says that Gets the System.Char object at a specified position in the current System.String
public char this[int index] { get; }