В чем разница между String и String в C#?

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

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

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

Ответов (25)

Решение

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

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

например

string place = "world";

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

например

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

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

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

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

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

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

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

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

Нет большой разницы между string и String в C#.

String - это класс в платформе .NET в пространстве имен System. Полное имя - System.String . Строка в нижнем регистре - это псевдоним System.String .

Но его рекомендуется использовать string при объявлении таких переменных, как:

string str = "Hello";

И мы можем использовать String любой встроенный метод для таких строк, как String.IsNullOrEmpty() .

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

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

Но теперь длинный текстовый ответ.

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

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

« System.String » Ака «String» (капитал «S») представляет собой .NET тип данных , в то время как структура «строка» представляет собой C# тип данных.

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

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

String s = "I am String";

или

string s = "I am String";

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

object:, System.Object string:, System.String bool:, System.Boolean byte:, System.Byte sbyte:, System.SByte short: System.Int16 и т. д.

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

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

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

string s = String.ToUpper() ;

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

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

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

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

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

Лучший ответ, который я когда-либо слышал об использовании предоставленных псевдонимов типов в 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 и т. Д. Хотя писать следующий код законно, строка с float кажется мне очень неестественной, и неочевидно, что строка правильная:
BinaryReader br = new BinaryReader(...);
float val  = br.ReadSingle(); // OK, but feels unnatural
Single val = br.ReadSingle(); // OK and feels good

Вот и все. Я думаю, что все это действительно хорошие моменты. Однако я не использую советы Джеффри в своем собственном коде. Возможно, я слишком застрял в своем мире C#, но в конечном итоге я пытаюсь сделать свой код похожим на код фреймворка.

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

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

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

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

Рассмотреть возможность:

String someString; 
string anotherString; 

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

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

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

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

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

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

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

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

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

Как отмечали другие, string это псевдоним для System.String . Предполагая, что ваш код String компилируется в System.String (т.е. у вас нет директивы using для какого-либо другого пространства имен с другим 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 классы.

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

As the others are saying, they're the same. StyleCop rules, by default, will enforce you to use string as a C# code style best practice, except when referencing System.String static functions, such as String.Format, String.Join, String.Concat, etc...

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

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

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

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

StringBuilder @string = new StringBuilder();

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

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

string это тип в C#.

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

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

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

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

Спецификация языка 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 и т. Д. Хотя писать следующий код законно, строка с float кажется мне очень неестественной, и неочевидно, что строка правильная:

    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 метод.

Я не узнал его мнения, пока не прочитал весь абзац.

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

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