В чем разница между строкой и строкой в C#?
Пример (обратите внимание на случай):
string s = "Hello world!";
String s = "Hello world!";
Каковы правила использования каждого из них? И в чем различия?
75 ответов
string
это псевдоним в C# для System.String
,
Технически, нет никакой разницы. Это как int
против System.Int32
,
Что касается руководящих принципов, как правило, рекомендуется использовать string
в любое время вы имеете в виду объект.
например
string place = "world";
Кроме того, я думаю, что обычно рекомендуется использовать String
если вам нужно обратиться конкретно к классу.
например
string greet = String.Format("Hello {0}!", place);
Это стиль, который Microsoft стремится использовать в своих примерах.
Похоже, что руководство в этой области, возможно, изменилось, поскольку StyleCop теперь обеспечивает использование псевдонимов, специфичных для C#.
Просто для полноты, вот мозговая свалка соответствующей информации...
Как отметили другие, string
это псевдоним для System.String
, Они компилируются в один и тот же код, поэтому во время выполнения нет никакой разницы. Это только один из псевдонимов в C#. Полный список:
object: System.Object
string: System.String
bool: System.Boolean
byte: System.Byte
sbyte: System.SByte
short: System.Int16
ushort: System.UInt16
int: System.Int32
uint: System.UInt32
long: System.Int64
ulong: System.UInt64
float: System.Single
double: System.Double
decimal: System.Decimal
char: System.Char
Помимо string
а также object
псевдонимы - все для значений типов. decimal
это тип значения, но не примитивный тип в CLR. Единственный примитивный тип, у которого нет псевдонима, System.IntPtr
,
В спецификации псевдонимы типа значения известны как "простые типы". Литералы могут использоваться для постоянных значений любого простого типа; никакие другие типы значений не имеют доступных литеральных форм. (Сравните это с VB, который позволяет DateTime
литералы, и псевдоним для этого тоже.)
Есть одно обстоятельство, при котором вы должны использовать псевдонимы: при явном указании базового типа перечисления. Например:
public enum Foo : UInt32 {} // Invalid
public enum Bar : uint {} // Valid
Это просто вопрос того, как спецификация определяет объявления enum - часть после двоеточия должна быть продукцией целочисленного типа, что является одним из токенов sbyte
, byte
, short
, ushort
, int
, uint
, long
, ulong
, char
... в отличие от производства типов, используемого, например, объявлениями переменных. Это не указывает на другую разницу.
Наконец, когда дело доходит до использования: лично я использую псевдонимы везде для реализации, но тип CLR для любых API. На самом деле не имеет большого значения, какую вы используете с точки зрения реализации - согласованность в вашей команде - это хорошо, но больше никого не волнует. С другой стороны, очень важно, что если вы ссылаетесь на тип в API, вы делаете это не зависящим от языка способом. Метод называется ReadInt32
однозначно, тогда как метод называется ReadInt
требует интерпретации. Вызывающий может использовать язык, который определяет int
псевдоним для Int16
, например. Разработчики фреймворка.NET следовали этому шаблону, хорошие примеры были в BitConverter
, BinaryReader
а также Convert
классы.
String
обозначает System.String
и это тип.NET Framework. string
это псевдоним в языке C# для System.String
, Они оба скомпилированы в System.String
в IL (Intermediate Language), поэтому нет никакой разницы. Выберите то, что вам нравится, и используйте это. Если вы код в C#, я бы предпочел string
так как это псевдоним типа C# и хорошо известен программистам C#.
Я могу сказать то же самое о ( int
, System.Int32
) и т. д.
Лучший ответ, который я когда-либо слышал об использовании предоставленных псевдонимов типов в C#, дан Джеффри Рихтером в его книге CLR Via C#. Вот его 3 причины:
- Я видел, что некоторые разработчики были сбиты с толку, не зная, использовать ли в своем коде строку или строку. Поскольку в C# строка (ключевое слово) отображается точно в System.String (тип FCL), нет никакой разницы, и любой из них может быть использован.
- В C# long отображается на System.Int64, но на другом языке программирования long может отображаться на Int16 или Int32. На самом деле, C++/CLI фактически обрабатывает долго как Int32. Кто-то, читающий исходный код на одном языке, может легко неверно истолковать намерение кода, если он или она привыкли к программированию на другом языке программирования. На самом деле, большинство языков даже не воспринимают ключевое слово как долго и не компилируют код, который его использует.
- В FCL есть много методов, имена которых являются частью имен их методов. Например, тип BinaryReader предлагает такие методы, как ReadBoolean, ReadInt32, ReadSingle и т. Д., А тип System.Convert предлагает такие методы, как ToBoolean, ToInt32, ToSingle и т. Д. Хотя написать следующий код законно, строка с плавающей точкой кажется мне неестественной, и не очевидно, что строка правильная:
BinaryReader br = new BinaryReader(...);
float val = br.ReadSingle(); // OK, but feels unnatural
Single val = br.ReadSingle(); // OK and feels good
Так что у вас есть это. Я думаю, что это действительно хорошие моменты. Однако я не использую советы Джеффри в своем собственном коде. Может быть, я слишком застрял в своем мире C#, но в итоге я пытаюсь сделать мой код похожим на фреймворк.
string
это зарезервированное слово, но String
это просто имя класса. Это означает, что string
не может использоваться как имя переменной само по себе.
Если по какой-то причине вам нужна переменная с именем string, вы увидите только первый из этих компиляций:
StringBuilder String = new StringBuilder(); // compiles
StringBuilder string = new StringBuilder(); // doesn't compile
Если вы действительно хотите имя переменной с именем string, вы можете использовать @
в качестве префикса:
StringBuilder @string = new StringBuilder();
Еще одно критическое отличие: переполнение стека выделяет их по-разному.
Есть одно отличие - вы не можете использовать String
без using System;
заранее.
Это было покрыто выше; тем не менее, вы не можете использовать string
в отражении; ты должен использовать String
,
System.String
это класс строки.NET - в C# string
это псевдоним для System.String
- поэтому в использовании они одинаковы.
Что касается руководящих принципов, я бы не стал слишком зацикливаться и просто использовать то, что вам хочется - в жизни есть более важные вещи, и в любом случае код будет таким же.
Если вы обнаружите, что строите системы, в которых необходимо указать размер целых чисел, которые вы используете, и поэтому склонны использовать Int16
, Int32
, UInt16
, UInt32
и т.д. тогда это может выглядеть более естественным в использовании String
- и при перемещении между различными языками.net это может сделать вещи более понятными - в противном случае я бы использовал string и int.
Я предпочитаю с заглавной буквы .NET
типы (а не псевдонимы) по причинам форматирования. .NET
типы окрашиваются так же, как и другие типы объектов (в конце концов, типы значений являются собственными объектами).
Условные и контрольные ключевые слова (например, if
, switch
, а также return
) строчные и темно-синие (по умолчанию). И я бы предпочел не иметь разногласий в использовании и формате.
Рассматривать:
String someString;
string anotherString;
string
а также String
идентичны во всех отношениях (кроме заглавной буквы "S"). В любом случае нет никаких последствий для производительности.
Строчные string
предпочтительнее в большинстве проектов из-за подсветки синтаксиса
Это видео на YouTube демонстрирует, насколько они отличаются.
Но теперь для длинного текстового ответа.
Когда мы говорим о .NET
Есть две разные вещи, одна есть .NET
рамки и другие есть языки (C#
, VB.NET
и т.д.) которые используют эту структуру.
" System.String
"ака" Строка " (заглавная"S") является .NET
тип данных структуры, в то время как "строка" является C#
тип данных.
Короче говоря, "String" - это псевдоним (то же самое, что называется с разными именами) "string". Таким образом, технически оба приведенных ниже кода дают одинаковый результат.
String s = "I am String";
или же
string s = "I am String";
Таким же образом существуют псевдонимы для другого типа данных C#, как показано ниже:
объект: System.Object
строка: System.String
, bool: System.Boolean
, байт: System.Byte
, sbyte: System.SByte
, короткая: System.Int16
и так далее
Теперь вопрос на миллион долларов с точки зрения программиста. Так когда же использовать "String" и "string"?
Во-первых, чтобы избежать путаницы, используйте один из них последовательно. Но с точки зрения передового опыта, когда вы делаете объявление переменной, лучше использовать "string" (маленькие "s"), а когда вы используете его в качестве имени класса, тогда "String" (заглавная "S") предпочтительнее.
В приведенном ниже коде левая часть представляет собой объявление переменной, и оно объявлено с использованием "строки". В правой части мы вызываем метод, поэтому "String" более разумно.
string s = String.ToUpper() ;
C#- это язык, который используется вместе с CLR.
string
это тип в C#.
System.String
это тип в CLR.
Когда вы используете C# вместе с CLR string
будет сопоставлен с System.String
,
Теоретически, вы могли бы реализовать C#-компилятор, который генерировал байт-код Java. Разумная реализация этого компилятора, вероятно, отобразит string
в java.lang.String
для того, чтобы взаимодействовать с библиотекой времени выполнения Java.
Нижний регистр string
это псевдоним для System.String
, Они одинаковы в C#
,
Есть спор о том, следует ли вам использовать типы системы (System.Int32
, System.String
и т. д.) типа или C# aliases
(int
, string
, так далее). Я лично считаю, что вы должны использовать C# aliases
, но это только мое личное предпочтение.
string
это просто псевдоним для System.String
, Компилятор будет относиться к ним одинаково.
Единственное практическое отличие - это выделение синтаксиса, как вы упомянули, и то, что вы должны написать using System
если вы используете String
,
Оба одинаковы. Но с точки зрения принципов кодирования лучше использовать string
вместо String
, Это то, что обычно используют разработчики. например, вместо использования Int32
мы используем int
как int
псевдоним Int32
К вашему сведению "Строка ключевого слова - это просто псевдоним для предопределенного класса System.String
.” - C# Спецификация языка 4.2.3 http://msdn2.microsoft.com/En-US/library/aa691153.aspx
Как говорят другие, они одинаковы. Правила StyleCop по умолчанию заставят вас использовать string
в качестве наилучшей практики стиля кода C#, за исключением ссылок System.String
статические функции, такие как String.Format
, String.Join
, String.Concat
, так далее...
Новый ответ через 6 лет и 5 месяцев (промедление).
В то время как string
является зарезервированным ключевым словом C#, которое всегда имеет фиксированное значение, String
это просто обычный идентификатор, который может ссылаться на что угодно. В зависимости от членов текущего типа, текущего пространства имен и примененного using
директивы и их размещение, String
может быть значением или типом, отличным от global::System.String
,
Я приведу два примера, где using
директивы не помогут.
Во-первых, когда String
является значением текущего типа (или локальной переменной):
class MySequence<TElement>
{
public IEnumerable<TElement> String { get; set; }
void Example()
{
var test = String.Format("Hello {0}.", DateTime.Today.DayOfWeek);
}
}
Выше не будет компилироваться, потому что IEnumerable<>
не имеет нестатического члена с именем Format
и методы расширения не применяются. В приведенном выше случае все еще возможно использовать String
в других контекстах, где тип является единственной возможностью синтаксически. Например String local = "Hi mum!";
может быть в порядке (в зависимости от пространства имен и using
директивы).
Хуже: Сказать String.Concat(someSequence)
будет скорее всего (в зависимости от using
s) перейти к методу расширения Linq Enumerable.Concat
, Это не пойдет на статический метод string.Concat
,
Во-вторых, когда String
это другой тип, вложенный в текущий тип:
class MyPiano
{
protected class String
{
}
void Example()
{
var test1 = String.Format("Hello {0}.", DateTime.Today.DayOfWeek);
String test2 = "Goodbye";
}
}
Ни одно из утверждений в Example
метод компилируется. Вот String
всегда струна для фортепиано, MyPiano.String
, Нет участника (static
или нет) Format
существует на нем (или наследуется от его базового класса). И значение "Goodbye"
не может быть преобразован в него.
Использование типов системы упрощает портирование между C# и VB.Net, если вы увлекаетесь такими вещами.
Против того, что кажется обычной практикой среди других программистов, я предпочитаю String
над string
просто чтобы подчеркнуть тот факт, что String
это ссылочный тип, как упоминал Джон Скит.
string
псевдоним (или сокращение) System.String
, Это значит, набрав string
мы имели в виду System.String
, Вы можете прочитать больше в Think Link: 'строка' является псевдонимом / сокращением System.String.
Я просто хотел бы добавить это к ответу lfousts из книги Ritchers:
Спецификация языка C# гласит: "По стилю, использование ключевого слова предпочтительнее, чем использование полного имени типа системы". Я не согласен с языковой спецификацией; Я предпочитаю использовать имена типов FCL и полностью избегать имен примитивных типов. На самом деле, я бы хотел, чтобы компиляторы даже не предлагали имена примитивных типов и заставляли разработчиков использовать вместо них имена типов FCL. Вот мои причины:
Я не получил его мнение, прежде чем я прочитал полный параграф.
Строка (System.String
) является классом в библиотеке базовых классов. Строка (нижний регистр) - это зарезервированная работа в C#, которая является псевдонимом для System.String. Int32 vs int похожая ситуация как Boolean vs. bool
, Эти ключевые слова для языка C# позволяют объявлять примитивы в стиле, аналогичном C.
JaredPar (разработчик компилятора C# и плодотворный пользователь SO!) Написал отличную запись в блоге на эту тему. Я думаю, что здесь стоит поделиться. Это хороший взгляд на нашу тему.
string
противString
это не дебаты о стиле[...]
Ключевое слово
string
имеет конкретное значение в C#. Это типSystem.String
который существует в основной сборке времени выполнения. Среда выполнения по сути понимает этот тип и предоставляет возможности, ожидаемые разработчиками для строк в.NET. Его присутствие настолько критично для C#, что, если этот тип не существует, компилятор завершит работу, прежде чем попытаться даже проанализировать строку кода. следовательноstring
имеет точное, однозначное значение в коде C#.Идентификатор
String
хотя не имеет конкретного значения в C#. Это идентификатор, который проходит через все правила поиска имен, какWidget
,Student
и т. д. Он может связываться со строкой или связываться с типом в другой сборке, цели которого могут отличаться отstring
, Хуже того, это может быть определено таким образом, чтобы кодString s = "hello"
; продолжил компилировать.class TricksterString { void Example() { String s = "Hello World"; // Okay but probably not what you expect. } } class String { public static implicit operator String(string s) => null; }
Фактическое значение
String
всегда будет зависеть от разрешения имени. Это означает, что это зависит от всех исходных файлов в проекте и всех типов, определенных во всех ссылочных сборках. Короче говоря, для понимания того, что это значит, требуется немало контекста.Правда, в подавляющем большинстве случаев
String
а такжеstring
будет привязан к тому же типу. Но используяString
все еще означает, что разработчики оставляют свою программу на интерпретацию в местах, где есть только один правильный ответ. когдаString
связывает с неправильным типом, это может оставить разработчиков отладкой на несколько часов, регистрируя ошибки в команде компилятора и вообще тратя время, которое можно было бы сэкономить, используяstring
,Другой способ визуализировать разницу с этим примером:
string s1 = 42; // Errors 100% of the time String s2 = 42; // Might error, might not, depends on the code
Многие будут утверждать, что в то время как это технически точная информация, используя
String
все еще в порядке, потому что очень редко кодовая база определяет тип этого имени. Или что когдаString
определяется как признак плохой базы кода.[...]
Вы увидите, что
String
определяется для ряда полностью допустимых целей: помощников по отражению, библиотек сериализации, лексеров, протоколов и т. д. Для любой из этих библиотекString
противstring
имеет реальные последствия в зависимости от того, где используется код.Помните, когда вы видите
String
противstring
Спор это о семантике, а не о стиле. Выбор строки дает четкий смысл вашей кодовой базе. ВыборString
не ошибаюсь, но он оставляет дверь открытой для сюрпризов в будущем.
Примечание: я скопировал / вставил большую часть сообщения в блоге по причине архива. Я игнорирую некоторые части, поэтому я рекомендую пропустить и прочитать сообщение в блоге, если можете.
Это действительно условно. string
просто больше похоже на стиль C/C++. Общее соглашение состоит в том, чтобы использовать любые ярлыки, предоставленные выбранным вами языком (int/Int для Int32
). Это относится к "объекту" и decimal
также.
Теоретически это может помочь перенести код в какой-то будущий 64-битный стандарт, в котором "int" может означать Int64
, но это не главное, и я ожидаю, что любой мастер обновления изменит любое int
ссылки на Int32
в любом случае, просто чтобы быть в безопасности.
String
не является ключевым словом и может использоваться как идентификатор, тогда как string
является ключевым словом и не может использоваться в качестве идентификатора. И с функциональной точки зрения оба одинаковы.
Опаздываю на вечеринку: я использую типы CLR 100% времени (ну, за исключением случаев, когда я вынужден использовать тип C#, но я не помню, когда это было в последний раз).
Первоначально я начал делать это несколько лет назад, в соответствии с книгами CLR Ричи. Для меня имело смысл, что в конечном итоге все языки CLR должны поддерживать набор типов CLR, поэтому использование типов CLR самостоятельно обеспечивает более четкий и, возможно, более "многократно используемый" код.
Теперь, когда я делал это годами, это привычка, и мне нравится цвет, который VS показывает для типов CLR.
Единственный реальный недостаток заключается в том, что автозаполнение использует тип C#, поэтому я в итоге перепечатываю автоматически сгенерированные типы, чтобы вместо этого указать тип CLR.
Кроме того, теперь, когда я вижу "int" или "string", для меня это выглядит просто неправильно, как будто я смотрю на C-код 1970-х годов.
Нет никакой разницы.
Ключевое слово C# string
сопоставляется с типом.NET System.String
- это псевдоним, который придерживается правил именования языка.
Так же, int
карты для System.Int32
,
По этому вопросу есть цитата из книги Дэниела Солиса.
Все предопределенные типы отображаются непосредственно в базовые типы.NET. Имена типов C# (string) являются просто псевдонимами для типов.NET (String или System.String), поэтому использование имен.NET синтаксически работает нормально, хотя это не рекомендуется. В программе на C# вы должны использовать имена C#, а не имена.NET.
Строка является ключевым словом, и вы не можете использовать строку в качестве идентификатора.
Строка не является ключевым словом, и вы можете использовать ее в качестве идентификатора:
пример
string String = "I am a string";
Ключевое слово string
это псевдоним для System.String
кроме вопроса о ключевых словах, они точно эквивалентны.
typeof(string) == typeof(String) == typeof(System.String)