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


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 .

Question

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

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

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




Это видео 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() ;



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




New answer after 6 years and 5 months (procrastination).

While string is a reserved C# keyword that always has a fixed meaning, String is just an ordinary identifier which could refer to anything. Depending on members of the current type, the current namespace and the applied using directives and their placement, String could be a value or a type distinct from global::System.String .

I shall provide two examples where using directives will not help .

First, when String is a value of the current type (or a local variable):

class MySequence<TElement>
{
  public IEnumerable<TElement> String { get; set; }

  void Example()
  {
    var test = String.Format("Hello {0}.", DateTime.Today.DayOfWeek);
  }
}

The above will not compile because IEnumerable<> does not have a non-static member called Format , and no extension methods apply. In the above case, it may still be possible to use String in other contexts where a type is the only possibility syntactically. For example String local = "Hi mum!"; could be OK (depending on namespace and using directives).

Worse: Saying String.Concat(someSequence) will likely (depending on using s) go to the Linq extension method Enumerable.Concat . It will not go to the static method string.Concat .

Secondly, when String is another type , nested inside the current type:

class MyPiano
{
  protected class String
  {
  }

  void Example()
  {
    var test1 = String.Format("Hello {0}.", DateTime.Today.DayOfWeek);
    String test2 = "Goodbye";
  }
}

Neither statement in the Example method compiles. Here String is always a piano string , MyPiano.String . No member ( static or not) Format exists on it (or is inherited from its base class). And the value "Goodbye" cannot be converted into it.




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

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




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




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

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




Yes, that's no difference between them, just like the bool and Boolean .




There is no difference between the two - string , however, appears to be the preferred option when considering other developers' source code.




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

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

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




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 года.




Лучший ответ, который я когда-либо слышал об использовании предоставленных псевдонимов типов в 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 и String идентичны во всех отношениях (кроме прописных букв «S»). В любом случае, никаких последствий для производительности не существует.

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




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




Related