В чем разница между строкой и строкой в ​​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) будет скорее всего (в зависимости от usings) перейти к методу расширения 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)

Да, между ними нет разницы, как bool а также Boolean,

Другие вопросы по тегам