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





15 Answers

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

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

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

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

сравнение замена символа

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

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

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




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

  • Я видел, как некоторые разработчики смущались, не зная, следует ли использовать строку или строку в их коде. Потому что в C # строка (ключевое слово) точно сопоставляется с System.String (тип FCL), нет никакой разницы и может быть использована.
  • В C #, long maps to 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 без using System; заранее.




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

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

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




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

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




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

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

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

« System.String » aka «String» («S») - это тип данных .NET а «строка» - тип данных C# .

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

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»?

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

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

string s = String.ToUpper() ;



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

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




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




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




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




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

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

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

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

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




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

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




Новый ответ через 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всегда пианино string , MyPiano.String. На нем нет ( staticили нет) Format(или унаследован от его базового класса). И значение "Goodbye"не может быть преобразовано в него.




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

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

пример

string String = "I am a string";

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

 typeof(string) == typeof(String) == typeof(System.String)



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




Related