Язык программирования C#9 и платформа .NET5 - Эндрю Троелсен
Шрифт:
Интервал:
Закладка:
string greeting = string.Format("Hello {0} you are {1} years old.",
name.ToUpper(), age);
string greeting2 = $"Hello {name.ToUpper()} you are {age} years old.";
Здесь посредством вызова ToUpper() производится преобразование значения name в верхний регистр. Обратите внимание, что при подходе с интерполяцией строк завершающая пара круглых скобок к вызову данного метода не добавляется. Учитывая это, использовать область видимости, определяемую фигурными скобками, как полноценную область видимости метода, которая содержит многочисленные строки исполняемого кода, невозможно. Взамен допускается только вызывать одиночный метод на объекте с применением операции точки, а также определять простое общее выражение наподобие {age += 1}.
Полезно также отметить, что в рамках нового синтаксиса внутри строкового литерала по-прежнему можно использовать управляющие последовательности. Таким образом, для вставки символа табуляции необходимо применять последовательность t:
string greeting = string.Format("tHello {0} you are {1} years old.",
name.ToUpper(), age);
string greeting2 = $"tHello {name.ToUpper()} you are {age} years old.";
Определение дословных строк (обновление в версии 8.0)
Когда вы добавляете к строковому литералу префикс @, то создаете так называемую дословную строку. Используя дословные строки, вы отключаете обработку управляющих последовательностей в литералах и заставляете выводить значения string в том виде, как есть. Такая возможность наиболее полезна при работе со строками, представляющими пути к каталогам и сетевым ресурсам. Таким образом, вместо применения управляющей последовательности \ можно поступить следующим образом:
// Следующая строка воспроизводится дословно,
// так что отображаются все управляющие символы.
Console.WriteLine(@"C:MyAppbinDebug");
Также обратите внимание, что дословные строки могут использоваться для предохранения пробельных символов в строках, разнесенных по нескольким строкам вывода:
// При использовании дословных строк пробельные символы предохраняются.
string myLongString = @"This is a very
very
very
long string";
Console.WriteLine(myLongString);
Применяя дословные строки, в литеральную строку можно также напрямую вставлять символы двойной кавычки, просто дублируя знак ":
Console.WriteLine(@"Cerebus said ""Darrr! Pret-ty sun-sets""");
Дословные строки также могут быть интерполированными строками за счет указания операций интерполяции ($) и дословности (@):
string interp = "interpolation";
string myLongString2 = $@"This is a very
very
long string with {interp}";
Нововведением в версии C# 8 является то, что порядок следования этих операций не имеет значения. Работать будет либо $@ либо @$.
Работа со строками и операциями равенства
Как будет подробно объясняться в главе 4, ссылочный тип — это объект, размещаемый в управляемой куче со сборкой мусора. По умолчанию при выполнении проверки на предмет равенства ссылочных типов (с помощью операций == и ! = языка С#) значение true будет возвращаться в случае, если обе ссылки указывают на один и тот же объект в памяти. Однако, несмотря на то, что тип string в действительности является ссылочным, операции равенства для него были переопределены так, чтобы можно было сравнивать значения объектов string, а не ссылки на объекты в памяти.
static void StringEquality()
{
Console.WriteLine("=> String equality:");
string s1 = "Hello!";
string s2 = "Yo!";
Console.WriteLine("s1 = {0}", s1);
Console.WriteLine("s2 = {0}", s2);
Console.WriteLine();
// Проверить строки на равенство.
Console.WriteLine("s1 == s2: {0}", s1 == s2);
Console.WriteLine("s1 == Hello!: {0}", s1 == "Hello!");
Console.WriteLine("s1 == HELLO!: {0}", s1 == "HELLO!");
Console.WriteLine("s1 == hello!: {0}", s1 == "hello!");
Console.WriteLine("s1.Equals(s2): {0}", s1.Equals(s2));
Console.WriteLine("Yo!.Equals(s2): {0}", "Yo!".Equals(s2));
Console.WriteLine();
}
Операции равенства C# выполняют в отношении объектов string посимвольную проверку равенства с учетом регистра и нечувствительную к культуре. Следовательно, строка "Hello!" не равна строке "HELLO!" и также отличается от строки "hello!". Кроме того, памятуя о связи между string и System.String, проверку на предмет равенства можно осуществлять с использованием метода Equals() класса String и других поддерживаемых им операций равенства. Наконец, поскольку каждый строковый литерал (такой как "Yo!") является допустимым экземпляром System.String, доступ к функциональности, ориентированной на работу со строками, можно получать для фиксированной последовательности символов.
Модификация поведения сравнения строк
Как уже упоминалось, операции равенства строк (Compare(), Equals() и ==), а также функция IndexOf() по умолчанию чувствительны к регистру символов и нечувствительны к культуре. Если ваша программа не заботится о регистре символов, тогда может возникнуть проблема. Один из способов ее преодоления предполагает преобразование строк в верхний или нижний регистр с последующим их сравнением:
if (firstString.ToUpper() == secondString.ToUpper())
{
// Делать что-то
}
Здесь создается копия каждой строки со всеми символами верхнего регистра. В большинстве ситуаций это не проблема, но в случае очень крупных строк может пострадать производительность. И дело даже не производительности — написание каждый раз такого кода преобразования становится утомительным. А что, если вы забудете вызвать ToUpper()? Результатом будет трудная в обнаружении ошибка.
Гораздо лучший прием предусматривает применение перегруженных версий перечисленных ранее методов, которые принимают значение перечисления StringComparison, управляющего выполнением сравнения. Значения StringComparison описаны в табл. 3.7.
Чтобы взглянуть на результаты применения StringComparison, создайте новый метод по имени StringEqualitySpecifyingCompareRules() со следующим кодом:
static void StringEqualitySpecifyingCompareRules()
{
Console.WriteLine("=> String equality (Case Insensitive:");
string s1 = "Hello!";
string s2 = "HELLO!";
Console.WriteLine("s1 = {0}", s1);
Console.WriteLine("s2 = {0}", s2);
Console.WriteLine();
// Проверить результаты изменения стандартных правил сравнения.
Console.WriteLine("Default rules: s1={0},s2={1}s1.Equals(s2): {2}",
s1, s2, s1.Equals(s2));
Console.WriteLine("Ignore case: s1.Equals(s2,
StringComparison.OrdinalIgnoreCase): {0}",
s1.Equals(s2, StringComparison.OrdinalIgnoreCase));
Console.WriteLine("Ignore case, Invariant Culture: s1.Equals(s2,
StringComparison.InvariantCultureIgnoreCase): {0}",
s1.Equals(s2, StringComparison.InvariantCultureIgnoreCase));
Console.WriteLine();