Is string actually an array of chars or does it just have an indexer?

后端 未结 12 1819
無奈伤痛
無奈伤痛 2020-12-06 09:58

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

相关标签:
12条回答
  • 2020-12-06 10:21

    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#.

    0 讨论(0)
  • 2020-12-06 10:22

    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.

    0 讨论(0)
  • 2020-12-06 10:27

    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.

    0 讨论(0)
  • 2020-12-06 10:29

    Strings is simply not an array, in the sense that "Hello" is char[] is evaluated to false.

    0 讨论(0)
  • 2020-12-06 10:30

    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.

    0 讨论(0)
  • 2020-12-06 10:33

    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; }
    
    0 讨论(0)
提交回复
热议问题