C # - действительно ли строка является массивом символов или просто имеет индексатор? - PullRequest
14 голосов
/ 08 сентября 2010

Поскольку в C # возможен следующий код, меня интересует, является ли строка массивом символов:

string a="TEST";
char C=a[0]; // will be T

Ответы [ 12 ]

18 голосов
/ 08 сентября 2010

System.String не является массивом .NET Char, потому что это:

char[] testArray = "test".ToCharArray();

testArray[0] = 'T';

будет компилироваться, а это:

string testString = "test";

testString[0] = 'T';

не будет.Массивы Char являются изменяемыми, а Strings - нет.Кроме того, string is Array возвращает false, а char[] is Array возвращает true.

14 голосов
/ 08 сентября 2010

Нет, это не массив. Но у него есть индексатор. Лучшее из обоих миров.

5 голосов
/ 08 сентября 2010

Строки в .NET поддерживаются классом System.String, который внутренне использует набор небезопасных методов для манипулирования указателями на реальных строковых данных с использованием стандартных методов манипуляции с памятью C.

StringСам класс не содержит массив, но у него есть свойство indexer, которое позволяет обрабатывать данные, как если бы они были массивом.

3 голосов
/ 08 сентября 2010

Нет, String - это класс в .Net.Может поддерживаться массивом.но это не массив.Классы могут иметь индексаторы, и это то, что делает String.

См. Комментарии для уточнения этого утверждения: Насколько я понимаю, все строки хранятся в общем двоичном объекте.Из-за этого «foo» и «foo» указывают на одну и ту же точку в этом BLOB-объекте ... одна из причин, по которой строки неизменны в C #.

2 голосов
/ 20 июля 2016

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, которое возвращает символ при передаче индекса, см. изображение.Что ясно говорит о том, что получает объект System.Char в указанной позиции в текущей System.String

public char this[int index] { get; }
2 голосов
/ 09 сентября 2010

Чтобы добавить немного к ответу Скотта Дормана и Гуфы.Если вы используете Windbg и! DumpObject в строке 'abcd', вы получите что-то вроде этого.

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 байтов (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, вы увидите, что он, как говорит Скотт, либо выполняет небезопасный код, либо использует методы указателя для чтения данных с использованием m_firstChar и m_stringLength.

2 голосов
/ 08 сентября 2010

Строковый объект содержит непрерывный блок символов, как массив символов, но строковый объект не является и не содержит объект массива.

Компилятор знает, что строковая строка является неизменной,он может выполнять определенную оптимизацию при доступе к строке так же, как при оптимизации доступа к массиву.Поэтому, когда вы обращаетесь к строке по индексу, вполне вероятно, что код заканчивает тем, что обращался к строковым данным напрямую, а не вызывал свойство индексатора.

2 голосов
/ 08 сентября 2010

A string не является char[], хотя оно имеет .ToCharArray().Также у него есть индексатор, который позволяет вам получать индивидуальный доступ к символам, как вы показали.Вполне вероятно, что он был реализован с помощью массива внутри, но это детали реализации.

1 голос
/ 08 сентября 2010

Strings - это не массив, в том смысле, что "Hello" is char[] оценивается как false.

1 голос
/ 08 сентября 2010

Используя Reflector , мы видим, что строка реализует IEnumerable<char>. Таким образом, это не символьный массив, но по сути его можно использовать как единое целое.

public sealed class String : IComparable, ICloneable, IConvertible, IComparable<string>, IEnumerable<char>, IEnumerable, IEquatable<string>

EDIT:

Реализация IEnumerable<char> не означает, что тип будет проиндексирован. Я не хотел это передавать. Это означает, что вы можете перечислять его и использовать как коллекцию. Лучший способ сформулировать то, что я хотел сказать, это то, что строка не является массивом символов, а представляет собой набор символов. Спасибо за комментарий.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...