Язык программирования C#9 и платформа .NET5 - Троелсен Эндрю. Страница 63

// Здесь определен класс StringBuilder:

using System.Text;

Уникальность класса

StringBuilder
в том, что при вызове его членов производится прямое изменение внутренних символьных данных объекта (делая его более эффективным) без получения копии данных в модифицированном формате. При создании экземпляра
StringBuilder
начальные значения объекта могут быть заданы через один из множества конструкторов. Если вы не знакомы с понятием конструктора, тогда пока достаточно знать только то, что конструкторы позволяют создавать объект с начальным состоянием при использовании ключевого слова
new
. Взгляните на следующий пример применения
StringBuilder
:

static void FunWithStringBuilder()

{

  Console.WriteLine("=> Using the StringBuilder:");

  StringBuilder sb = new StringBuilder("**** Fantastic Games ****");

  sb.Append("\n");

  sb.AppendLine("Half Life");

  sb.AppendLine("Morrowind");

  sb.AppendLine("Deus Ex" + "2");

  sb.AppendLine("System Shock");

  Console.WriteLine(sb.ToString());

  sb.Replace("2", " Invisible War");

  Console.WriteLine(sb.ToString());

  Console.WriteLine("sb has {0} chars.", sb.Length);

  Console.WriteLine();

}

Здесь создается объект

StringBuilder
с начальным значением
"**** Fantastic Games ****"
. Как видите, можно добавлять строки в конец внутреннего буфера, а также заменять или удалять любые символы. По умолчанию
StringBuilder
способен хранить строку только длиной 16 символов или меньше (но при необходимости будет автоматически расширяться): однако стандартное начальное значение длины можно изменить посредством дополнительного аргумента конструктора:

// Создать экземпляр StringBuilder с исходным размером в 256 символов.

StringBuilder sb = new StringBuilder("**** Fantastic Games ****", 256);

При добавлении большего количества символов, чем в указанном лимите, объект

StringBuilder
скопирует свои данные в новый экземпляр и увеличит размер буфера на заданный лимит.

Сужающие и расширяющие преобразования типов данных

Теперь, когда вы понимаете, как работать с внутренними типами данных С#, давайте рассмотрим связанную тему преобразования типов данных. Создайте новый проект консольного приложения по имени

TypeConversions
и добавьте его в свое решение. Приведите код к следующему виду:

using System;

Console.WriteLine("***** Fun with type conversions *****");

// Сложить две переменные типа short и вывести результат.

short numb1 = 9, numb2 = 10;

Console.WriteLine("{0} + {1} = {2}",

  numb1, numb2, Add(numb1, numb2));

Console.ReadLine();

static int Add(int x, int y)

{

  return x + y;

}

Легко заметить, что метод

Add()
ожидает передачи двух параметров
int
. Тем не менее, в вызывающем коде ему на самом деле передаются две переменные типа
short
. Хотя это может выглядеть похожим на несоответствие типов данных, программа компилируется и выполняется без ошибок, возвращая ожидаемый результат 19.

Причина, по которой компилятор считает такой код синтаксически корректным, связана с тем, что потеря данных в нем невозможна. Из-за того, что максимальное значение для типа

short
(32 767) гораздо меньше максимального значения для типа
int
(2 147 483 647), компилятор неявно расширяет каждое значение
short
до типа
int
. Формально термин расширение используется для определения неявного восходящего приведения которое не вызывает потерю данных.

На заметку! Разрешенные расширяющие и сужающие (обсуждаются далее) преобразования, поддерживаемые для каждого типа данных С#, описаны в разделе "Type Conversion Tables in .NET" ("Таблицы преобразования типов в .NET") документации по .NET Core.

Несмотря на то что неявное расширение типов благоприятствовало в предыдущем примере, в других ситуациях оно может стать источником ошибок на этапе компиляции. Например, пусть для переменных

numb1
и
numb2
установлены значения, которые (при их сложении) превышают максимальное значение типа
short
. Кроме того, предположим, что возвращаемое значение метода
Add()
сохраняется в новой локальной переменной
short
, а не напрямую выводится на консоль.

static void Main(string[] args)

{

  Console.WriteLine("***** Fun with type conversions *****");

  <b>// Следующий код вызовет ошибку на этапе компиляции!</b>

  short numb1 = 30000, numb2 = 30000;

  short answer = Add(numb1, numb2);

  Console.WriteLine(&quot;{0} + {1} = {2}&quot;,

    numb1, numb2, answer);

  Console.ReadLine();

}

В данном случае компилятор сообщит об ошибке: