В чем разница между строкой и строкой в ​​C #?

c# .net string types alias

1000102 просмотра

30 ответа

16826 Репутация автора

Пример ( обратите внимание на случай ):

string s = "Hello world!";
String s = "Hello world!";

Каковы правила использования каждого из них? И в чем различия ?

Автор: Lance Fisher Источник Размещён: 10.08.2008 07:18

Ответы (30)


5726 плюса

40614 Репутация автора

Решение

stringпсевдоним в C # для System.String.
Технически, нет никакой разницы. Это как int против System.Int32 .

Что касается руководящих принципов, обычно рекомендуется использовать stringлюбое время, когда вы ссылаетесь на объект.

например

string place = "world";

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

например

string greet = String.Format("Hello {0}!", place);

Это стиль, который Microsoft стремится использовать в своих примерах .

Похоже, что руководство в этой области, возможно, изменилось, поскольку StyleCop теперь обеспечивает использование псевдонимов, специфичных для C #.

Автор: Derek Park Размещён: 10.08.2008 07:22

238 плюса

6411 Репутация автора

System.Stringэто строковый класс .NET - в C # stringэто псевдоним для System.String- поэтому при использовании они одинаковы.

Что касается руководящих принципов, я бы не стал слишком зацикливаться и просто использовать то, что вам хочется - в жизни есть более важные вещи, и код все равно останется прежним.

Если вы нашли себя построение системы , где необходимо указать размер целых чисел , которые вы используете , и поэтому , как правило, используют Int16, Int32, UInt16, и UInt32т.д. , то это могло бы выглядеть более естественно использовать String- и, передвигаясь между различными языками .NET это может сделать вещи более понятными - иначе я бы использовал string и int.

Автор: Ronnie Размещён: 10.08.2008 07:26

152 плюса

21511 Репутация автора

Нижний регистр stringявляется псевдонимом для System.String. Они одинаковые в C#.

Спорят о том, следует ли вам использовать типы System ( System.Int32, System.Stringи т. Д.) Или C# aliases( int, stringи т. Д.). Я лично считаю, что вы должны использовать C# aliases, но это только мое личное предпочтение.

Автор: urini Размещён: 10.08.2008 07:27

477 плюса

1739 Репутация автора

Лучший ответ, который я когда-либо слышал об использовании предоставленных псевдонимов типов в 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 #, но в итоге я пытаюсь сделать мой код похожим на фреймворк.

Автор: Luke Foust Размещён: 15.08.2008 11:00

61 плюса

1838 Репутация автора

Это действительно условно. stringпросто больше похоже на стиль C / C ++. Общее соглашение состоит в том, чтобы использовать любые ярлыки, предоставленные выбранным вами языком (int / Int для Int32). Это относится и к «объекту» decimal.

Теоретически это может помочь перенести код в какой-то будущий 64-битный стандарт, в котором может означать «int» Int64, но это не главное, и я ожидаю, что любой мастер обновления изменит любые intссылки на так Int32или иначе, чтобы быть безопасным.

Автор: Mel Размещён: 18.08.2008 05:58

369 плюса

389 Репутация автора

Есть одно отличие - вы не можете использовать Stringбез using System;заранее.

Автор: user3296 Размещён: 27.08.2008 06:21

196 плюса

14635 Репутация автора

Я предпочитаю прописные .NETтипы (а не псевдонимы) по причинам форматирования. Эти .NETтипы окрашены так же , как и другие типы объектов (типы значений являются собственными объектами, в конце концов).

Условные и управляющие ключевые слова (например if, switchи return) строчные и темно-синие (по умолчанию). И я бы предпочел не иметь разногласий в использовании и формате.

Рассматривать:

String someString; 
string anotherString; 
Автор: Anthony Mastrean Размещён: 03.09.2008 06:58

93 плюса

21421 Репутация автора

Использование типов системы упрощает портирование между C # и VB.Net, если вы увлекаетесь такими вещами.

Автор: Ishmael Размещён: 22.09.2008 07:40

184 плюса

26301 Репутация автора

stringи Stringидентичны во всех отношениях (кроме заглавной буквы "S"). В любом случае нет никаких последствий для производительности.

Строчные буквы stringпредпочтительнее в большинстве проектов из-за подсветки синтаксиса

Автор: TheSoftwareJedi Размещён: 18.10.2008 04:50

148 плюса

11649 Репутация автора

stringэто просто псевдоним для System.String. Компилятор будет относиться к ним одинаково.

Единственное практическое отличие - это подсветка синтаксиса, которую вы упоминаете, и которую вы должны написать, using Systemесли используете String.

Автор: Hallgrim Размещён: 18.10.2008 04:50

675 плюса

4208 Репутация автора

Stringозначает, System.Stringи это тип .NET Framework. stringпсевдоним в языке C # для System.String. Оба они скомпилированы System.Stringв IL (промежуточный язык), поэтому нет никакой разницы. Выберите то, что вам нравится, и используйте это. Если вы пишете код на C #, я бы предпочел, так stringкак это псевдоним C # и хорошо известен программистам C #.

Я могу сказать то же самое о ( int, System.Int32) и т.д ..

Автор: artur02 Размещён: 18.10.2008 05:25

133 плюса

9884 Репутация автора

Оба одинаковы. Но с точки зрения принципов кодирования лучше использовать stringвместо String. Это то, что обычно используют разработчики. Например, вместо использования Int32мы используем intкак intпсевдоним дляInt32

К сведению «Строка ключевого слова - это просто псевдоним для предопределенного класса» System.String. - Спецификация языка C # 4.2.3 http://msdn2.microsoft.com/En-US/library/aa691153.aspx

Автор: Pradeep Kumar Mishra Размещён: 18.10.2008 06:26

3289 плюса

1125136 Репутация автора

Просто для полноты, вот мозговая свалка соответствующей информации ...

Как уже отмечали другие, 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

Это просто вопрос того, как спецификация определяет объявления перечислений - часть после двоеточия должен быть интегрально-типа производства, который один знак sbyte, byte, short, ushort, int, uint, long, ulong, char... , в отличие от типа производства , как используется в объявлениях переменных, например. Это не указывает на другую разницу.

Наконец, когда дело доходит до использования: лично я использую псевдонимы везде для реализации, но тип CLR для любых API. На самом деле не имеет большого значения, какой вы используете с точки зрения реализации - согласованность в вашей команде - это хорошо, но больше никого не волнует. С другой стороны, очень важно, что если вы ссылаетесь на тип в API, вы делаете это не зависящим от языка способом. Вызываемый метод ReadInt32является однозначным, тогда как вызываемый метод ReadIntтребует интерпретации. Вызывающий может использовать язык , например, для которого определяется intпсевдоним Int16. Каркасные .NET дизайнеры следовали этой модели, хорошие примеры будучи в BitConverter, BinaryReaderи Convertклассы.

Автор: Jon Skeet Размещён: 18.10.2008 06:52

297 плюса

7673 Репутация автора

Это было покрыто выше; тем не менее, вы не можете использовать stringв отражении; Вы должны использовать String.

Автор: TraumaPony Размещён: 19.10.2008 01:04

113 плюса

2241 Репутация автора

Как говорят другие, они одинаковы. Правила StyleCop, по умолчанию, будет обеспечивать , чтобы использовать в stringкачестве лучшей практики C # код стиля, за исключением ссылки на System.Stringстатические функции, такие как String.Format, String.Join, String.Concat, и т.д. ...

Автор: Lloyd Cotten Размещён: 19.10.2008 01:15

433 плюса

78607 Репутация автора

stringэто зарезервированное слово, но Stringэто просто имя класса. Это означает, что stringне может использоваться как имя переменной само по себе.

Если по какой-то причине вам нужна переменная с именем string , вы увидите только первый из этих компиляций:

StringBuilder String = new StringBuilder();  // compiles
StringBuilder string = new StringBuilder();  // doesn't compile 

Если вы действительно хотите имя переменной с именем string, вы можете использовать @в качестве префикса:

StringBuilder @string = new StringBuilder();

Еще одно критическое отличие: переполнение стека выделяет их по-разному.

Автор: Simon_Weaver Размещён: 24.02.2009 05:14

174 плюса

39129 Репутация автора

C # - это язык, который используется вместе с CLR.

string это тип в C #.

System.String это тип в CLR.

Когда вы используете C # вместе с CLR stringбудет отображаться на System.String.

Теоретически, вы могли бы реализовать C # -компилятор, который генерировал байт-код Java. Разумная реализация этого компилятора, вероятно карта stringдля java.lang.Stringтого , чтобы взаимодействовать с библиотекой времени выполнения Java.

Автор: Rasmus Faber Размещён: 17.03.2009 08:29

71 плюса

61 Репутация автора

Я просто хотел бы добавить это к ответу lfousts из книги Ritchers:

Спецификация языка C # гласит: «По стилю, использование ключевого слова предпочтительнее, чем использование полного имени типа системы». Я не согласен с языковой спецификацией; Я предпочитаю использовать имена типов FCL и полностью избегать имен примитивных типов. На самом деле, я бы хотел, чтобы компиляторы даже не предлагали имена примитивных типов и заставляли разработчиков использовать вместо них имена типов FCL. Вот мои причины:

  • Я видел, что некоторые разработчики были сбиты с толку, не зная, использовать ли в своем коде строку или строку . Поскольку в C # строка (ключевое слово) отображается точно на System.String (тип FCL), нет никакой разницы, и любой из них может быть использован. Точно так же я слышал, что некоторые разработчики говорят, что int представляет 32-разрядное целое число, когда приложение работает в 32-разрядной ОС, и что оно представляет 64-разрядное целое число, когда приложение выполняется в 64-разрядной ОС. Это утверждение абсолютно неверно: в C # int всегда отображается на System.Int32 , и поэтому оно представляет 32-разрядное целое число независимо от ОС, в которой выполняется код. Если бы программисты использовалиInt32 в своем коде, то эта потенциальная путаница также устранена.

  • В 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 #, склонны забывать, что другие языки программирования могут использоваться против CLR, и из-за этого C # -измы проникают в код библиотеки классов. Например, FCL Microsoft, почти исключительно написан на C # и разработчики в команде FCL теперь ввели методы в библиотеку , такие как массив «s GetLongLength , который возвращает Int64 значение , которое является длинным в C # , но не на других языках (например , C ++ / CLI). Другим примером может служить System.Linq.Enumerable «ы LongCount метод.

Я не получил его мнение, прежде чем я прочитал полный параграф.

Автор: claudioalpereira Размещён: 28.01.2011 10:08

65 плюса

91 Репутация автора

Stringне является ключевым словом и может использоваться в качестве идентификатора, тогда как stringявляется ключевым словом и не может использоваться в качестве идентификатора. И с функциональной точки зрения оба одинаковы.

Автор: user576533 Размещён: 25.04.2011 06:06

84 плюса

415 Репутация автора

Против того, что , как представляется, распространенной практикой среди других программистов, я предпочитаю Stringболее string, только чтобы подчеркнуть тот факт , что Stringэто ссылочный тип, как уже упоминалось Jon тарелочкам.

Автор: RolandK Размещён: 31.05.2011 11:20

33 плюса

3027 Репутация автора

Между этими двумя понятиями нет никакой разницы - stringоднако, кажется, что это предпочтительный вариант при рассмотрении исходного кода других разработчиков.

Автор: Dot NET Размещён: 24.08.2011 09:25

79 плюса

2144 Репутация автора

stringявляется псевдонимом (или сокращением) System.String. Это означает, что печатая, stringмы имели в виду System.String. Вы можете прочитать больше в Think Link: 'string' является псевдонимом / сокращением System.String.

Автор: JeeShen Lee Размещён: 21.10.2011 01:10

48 плюса

422478 Репутация автора

Нет никакой разницы.

Ключевое слово C # stringсоответствует типу .NET System.String- это псевдоним, который соответствует соглашениям об именах языка.

Аналогично, intкарты для System.Int32.

Автор: Oded Размещён: 14.01.2012 10:47

71 плюса

8054 Репутация автора

String ( System.String) - это класс в библиотеке базовых классов. Строка (нижний регистр) - это зарезервированная работа в C #, которая является псевдонимом для System.String. Int32 против int похожая ситуация как есть Boolean vs. bool. Эти ключевые слова, специфичные для языка C #, позволяют объявлять примитивы в стиле, аналогичном C.

Автор: Joe Alfano Размещён: 14.01.2012 10:51

65 плюса

2553 Репутация автора

Опаздываю на вечеринку: я использую типы CLR 100% времени (ну, за исключением случаев, когда вынужден использовать тип C #, но я не помню, когда это было в последний раз).

Первоначально я начал делать это несколько лет назад, в соответствии с книгами CLR Ричи. Для меня имело смысл, что в конечном итоге все языки CLR должны поддерживать набор типов CLR, поэтому использование типов CLR само по себе обеспечивает более четкий и, возможно, более «многократно используемый» код.

Теперь, когда я делал это годами, это привычка, и мне нравится цвет, который VS показывает для типов CLR.

Единственный реальный недостаток заключается в том, что автозаполнение использует тип C #, поэтому я в итоге перепечатываю автоматически сгенерированные типы, чтобы вместо этого указать тип CLR.

Кроме того, теперь, когда я вижу «int» или «string», для меня это выглядит просто неправильно, как будто я смотрю на C-код 1970-х годов.

Автор: Michael Ray Lovett Размещён: 24.08.2012 03:22

39 плюса

715 Репутация автора

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

Автор: Coder Размещён: 08.10.2012 08:22

43 плюса

4139 Репутация автора

По этому вопросу есть цитата из книги Дэниела Солиса .

Все предопределенные типы отображаются непосредственно в базовые типы .NET. Имена типов C # (string) являются просто псевдонимами для типов .NET (String или System.String), поэтому использование имен .NET синтаксически работает нормально, хотя это не рекомендуется. В программе на C # вы должны использовать имена C #, а не имена .NET.

Автор: user2771704 Размещён: 01.11.2013 03:21

161 плюса

18026 Репутация автора

Это видео на YouTube демонстрирует, насколько они отличаются.

Но теперь для длинного текстового ответа.

Когда мы говорим о .NETдвух разных вещах, одна - это .NETфреймворк, а другая - языки ( C#и VB.NETт. Д.) , Которые используют эту фреймворк.

введите описание изображения здесь

" System.String" aka "String" (заглавная "S") - это .NETтип данных структуры, а "string" - это C#тип данных.

введите описание изображения здесь

Короче говоря, «String» - это псевдоним (то же самое, что называется с разными именами) «string». Таким образом, технически оба приведенных ниже кода дают одинаковый результат.

String s = "I am String";

или же

string s = "I am String";

Таким же образом существуют псевдонимы для другого типа данных c #, как показано ниже:

object:, System.Objectstring:, System.Stringbool:, System.Booleanbyte:, System.Bytesbyte:, System.SByteshort: System.Int16и так далее

Теперь вопрос на миллион долларов с точки зрения программиста. Так когда же использовать «String» и «string»?

Прежде всего, чтобы избежать путаницы, используйте один из них последовательно. Но с точки зрения передового опыта, когда вы делаете объявление переменной, лучше использовать «string» (маленькие «s»), а когда вы используете его в качестве имени класса, тогда «String» (заглавная «S») предпочтительнее.

В приведенном ниже коде левая часть представляет собой объявление переменной, и оно объявлено с использованием «строки». В правой части мы вызываем метод, поэтому «String» более разумно.

string s = String.ToUpper() ;
Автор: Shivprasad Koirala Размещён: 15.01.2014 06:03

40 плюса

10200 Репутация автора

Строка является ключевым словом, и вы не можете использовать строку в качестве идентификатора.

Строка не является ключевым словом, и вы можете использовать его в качестве идентификатора:

пример

string String = "I am a string";

Ключевое слово string является псевдонимом System.Stringпомимо вопроса о ключевом слове, оба точно эквивалентны.

 typeof(string) == typeof(String) == typeof(System.String)
Автор: Neel Размещён: 11.06.2014 05:26

95 плюса

45115 Репутация автора

Новый ответ через 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"не может быть преобразована в это.

Автор: Jeppe Stig Nielsen Размещён: 15.01.2015 02:21
32x32