В чем разница между String и string в C#? Это разные типы?
Краткий ответ: это одно и то же. string — это просто псевдоним (alias) для System.String.
В C# нет никакой разницы между string и String. Это два имени для одного и того же типа — System.String. Ключевое слово string — это просто удобный псевдоним, который вводится языком C#, чтобы сделать код более читаемым и похожим на другие C-подобные языки.
Точно так же работают и другие встроенные псевдонимы:
int=System.Int32long=System.Int64bool=System.Booleandouble=System.Double
Это легко проверить. Следующий код скомпилируется и будет работать идеально:
using System;
class Program
{
static void Main()
{
// Оба объявления идентичны
string s1 = "Hello";
String s2 = "World";
// Проверяем типы
Console.WriteLine(s1.GetType() == typeof(string)); // True
Console.WriteLine(s2.GetType() == typeof(String)); // True
Console.WriteLine(s1.GetType() == typeof(String)); // True
Console.WriteLine(s2.GetType() == typeof(string)); // True
// Сравнение значений
Console.WriteLine(s1.Equals(s2)); // False (разные строки)
// Но можно даже смешивать:
String result = s1 + " " + s2;
Console.WriteLine(result); // Hello World
}
}
Когда использовать string, а когда String?
На практике существуют негласные правила (соглашения), которых придерживается большинство C#-разработчиков:
- Для объявления переменных, параметров и полей используйте
string(строчными буквами). Это стандарт, принятый в сообществе и в официальных руководствах Microsoft. - Для вызова статических методов класса String используйте
String(с заглавной буквы). Например:String.Format(),String.Join(),String.IsNullOrEmpty(). Хотя технически можно писать иstring.Format(), это выглядит необычно.
Пример правильного стиля:
string name = "Анна";
string greeting = String.Format("Привет, {0}!", name);
if (String.IsNullOrEmpty(name))
{
Console.WriteLine("Имя не указано");
}
Почему так сделано?
Это дизайнерское решение языка C#. Ключевые слова вроде string, int, bool были введены, чтобы:
- Сделать синтаксис более лаконичным (сравните
string xиSystem.String x). - Обеспечить единообразие с языками C/C++/Java, где также есть
string(хотя там это не псевдоним, а отдельный тип). - Избавить разработчика от необходимости писать
using System;для использования базовых типов.
Важно: string — это ссылочный тип (как и System.String), а не значимый. Несмотря на то, что строки ведут себя как значимые типы при сравнении (по значению, а не по ссылке), они хранятся в куче и являются неизменяемыми (immutable).
Итог: используйте string для переменных и String для статических методов. Но если вы перепутаете — компилятор не накажет. Главное — соблюдать единообразие в рамках одного проекта.
Дополнение: как это работает под капотом?
Когда вы пишете string s = "test";, компилятор C# на этапе компиляции преобразует string в System.String. В IL-коде (промежуточном языке) вы никогда не увидите string — только System.String. Это чисто синтаксический сахар.
Аналогия: в C# есть ключевое слово var, которое тоже заменяется на конкретный тип на этапе компиляции. Но в отличие от var, string — это не вывод типа, а жестко заданный псевдоним.
Есть один нюанс, о котором стоит знать: если вы работаете в среде, где нет using System; (например, в некоторых старых версиях Unity или в очень минималистичных проектах), то String без указания пространства имен не скомпилируется, а string будет работать всегда, так как ключевые слова языка не требуют импорта пространств имен.
Пример:
// Этот код НЕ скомпилируется без using System;
// String s = "test";
// А этот скомпилируется всегда
string s = "test";
Поэтому использование string считается более безопасным и переносимым. Но на практике в современных проектах вы почти всегда имеете using System; в начале файла, так что оба варианта равнозначны.