Hi, 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
Hi, 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, it's not an array. But it does have an indexer. Best of both worlds.
A string
is not an array of char
s until you convert it to one. The notation is simply used to access characters at different positions (indices) in a string.
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.
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#.
Using Reflector, we can see that string does implement IEnumerable<char>
. So, it is not a character array, but in essence can be used like one.
public sealed class String : IComparable, ICloneable, IConvertible, IComparable<string>, IEnumerable<char>, IEnumerable, IEquatable<string>
EDIT:
Implementing IEnumerable<char>
does not mean that the type will be indexed. I didn't mean to convey that. It means that you can enumerate over it and use it like a collection. A better way of wording what I meant to say is that a string isn't a character array, but is a collection of characters. Thanks for the comment.
A string object contains a continuous block of characers, just like an array of characters, but the string object neither is, nor contains an array object.
The compiler knows that the string string is immutable, so it can do certain optimisations when you access a string, in the same manner that it does optimisations when you access an array. So, when you access a string by index, it's likely that the code ends up accessing the string data directly rather than calling an indexer property.
System.String is not a .NET array of Char because this:
char[] testArray = "test".ToCharArray();
testArray[0] = 'T';
will compile, but this:
string testString = "test";
testString[0] = 'T';
will not. Char arrays are mutable, Strings are not. Also, string is Array
returns false, while char[] is Array
returns true.
Strings in .NET are backed by the System.String
class, which internally uses a bunch of unsafe methods to do pointer manipulation on the actual string data using standard C memory manipulation techniques.
The String
class itself does not contain an array, but it does have an indexer property which allows you to treat the data as if it were an array.
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.