В чем разница между строкой и строкой в ​​C #? - PullRequest
5963 голосов
/ 10 августа 2008

Пример ( обратите внимание на регистр ):

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

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

Ответы [ 61 ]

5609 голосов
/ 10 августа 2008

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

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

например.

string place = "world";

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

, например

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

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

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

3237 голосов
/ 18 октября 2008

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

Как уже отмечалось, 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 ... в отличие от производства type , используемого, например, объявлениями переменных. Никаких других отличий это не указывает.

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

656 голосов
/ 18 октября 2008

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

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

466 голосов
/ 16 августа 2008

Лучший ответ, который я когда-либо слышал об использовании предоставленных псевдонимов типов в C #, дан Джеффри Рихтером в его книге CLR Via C # . Вот его 3 причины:

  • Я видел, что некоторые разработчики были сбиты с толку, не зная, использовать ли string или String в их коде. Поскольку в C # строка (ключевое слово) точно соответствует System.String (тип FCL), различий нет, и их можно использовать.
  • В C # long отображается на System.Int64 , но на другом языке программирования long может отображаться на Int16 или Int32 . Фактически, C ++ / CLI действительно обрабатывает как Int32 . Кто-то, читающий исходный код на одном языке, может легко неверно истолковать намерение кода, если он или она привыкли к программированию на другом языке программирования. Фактически, большинство языков даже не воспринимают long как ключевое слово и не компилируют код, который его использует.
  • В FCL есть много методов, имена которых являются частью имен их методов. Например, тип BinaryReader предлагает такие методы, как ReadBoolean , ReadInt32 , ReadSingle и т. Д., А также система Тип .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 #, но в итоге я пытаюсь сделать мой код похожим на фреймворк.

420 голосов
/ 24 февраля 2009

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

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

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

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

StringBuilder @string = new StringBuilder();

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

363 голосов
/ 27 августа 2008

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

292 голосов
/ 19 октября 2008

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

234 голосов
/ 10 августа 2008

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

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

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

191 голосов
/ 03 сентября 2008

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

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

Рассмотрим:

String someString; 
string anotherString; 
180 голосов
/ 18 октября 2008

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

Нижний регистр string предпочтителен в большинстве проектов из-за подсветки синтаксиса

...