Суббота, 18.05.2024, 16:19
Приветствую Вас Гость | RSS
Форма входа
Поиск
Календарь
«  Май 2024  »
ПнВтСрЧтПтСбВс
  12345
6789101112
13141516171819
20212223242526
2728293031
Статистика

Онлайн всего: 1
Гостей: 1
Пользователей: 0

Charles Petzold ".NET Book Zero" Глава 5. Строки и консоль (II часть)

Многие из конструкторов string создают строки на основе указателей, но один создаёт строку из массива символов. Этот конструктор предлагает еще один подход, для замены символа в конкретной строке. Вы можете преобразовать строку в массив символов, заменить соответствующий элемент массива, а затем построить новую строку, основанную на массиве символов. В C#, в массивы объявляются после типа массива с пустыми двойными квадратными скобками:

char[] buffer = str.ToCharArray();
buffer[4] = 'e';
str = new string(buffer);

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

Как я уже упоминал, как строка псевдонимом класса System.String, ключевые слова char, int, и double в C# также псевдонимы. Но это не псевдонимы классов в пространстве имен System. Вместо этого, они являются псевдонимами для структур.

Разница между классами и структурами станет более очевидной в последующих разделах. Но во многих отношениях классы и структуры схожи, и вместо того, чтобы говорить "это моя переменная int", можно сказать, "это экземпляр структуры Int32" или "это объект типа Int32" или "это Объект Int32 ". Это, просто, придаёт такой скромной вещи немного более важный смысл.

Хотя вы не увидите никаких конструкторов, перечисленных в документации к Int32 и структуре Double, обе структуры имеют по умолчанию конструкторы без параметров, которые возвращают нулевые значения объекта. Таким образом, вместо инициализации int:

int index = 0;

Вы можете сделать следующим образом:

int index = new int();

Или так:

System.Int32 index = new int();

Или так:

int index = new System.Int32();

Или, если у вас есть, директива using для пространства имен System, тогда:

Int32 index = new Int32();

Или в любой другой комбинации. Все эти объявления являются эквивалентными. Начиная с .NET 2.0, вы также можете использовать ключевое слово default для получения значения по умолчанию в int:

int index = default(int);

Как вы видели в документации класса String, там есть много хороших причин, по которым тип данных String является псевдонимом для класса. Но есть ли причина для того, чтобы int и double типа являлись псевдонимами для структур Int32 и Double?

Конечно же! Обе структуры имеют метод экземпляра с именем ToString, который преобразует объект в строку. На самом деле, каждый класс и структуры в .NET Framework, в том числе и те, которые вы будете создавать сами – имеют метод экземпляра с именем ToString. Это происходит потому, что класс System.Object (также известный под C# псевдонимом object) определяет метод имени ToString. Класс System.Object является великим прародителем каждого класса .NET и каждой структуры, и все они наследуют этот замечательный метод ToString, и многие классы и структуры прикрепляют ToString к своим требованиям.

Рассмотрим следующий код:

int i = 55;
string str = i.ToString();

Метод ToString преобразует переменную int в строку, которой в данном случае является строка "55". Можно даже применить метод ToString напрямую к целому числу:

12345.ToString()

Этот вызов ToString возвратит строку "12345".

И это работает, как конкатенация строковых объектов с не строковыми объектами. Если переменная или строковый литерал находятся по обе стороны от знака плюс, а если не строковый объект находится с одной стороны, то он преобразуется в строку с помощью вызова его метода ToString. И это сработает всегда!

Ранее я показывал, как использовать статическое свойство NewLine из класса Environment. Класс Environment имеет и некоторые другие вкусности, которые могут дать вашей программе информацию о машине, на которой она работает. Далее мы приводим программу, которая показывает несколько таких пунктов.

ShowEnvironmentStuff.cs
//-----------------------------------------------------
// ShowEnvironmentStuff.cs (c) 2006 by Charles Petzold
//-----------------------------------------------------
using System;
 
class ShowEnvironmentStuff
{
    static void Main()
    {
        Console.WriteLine("My Documents is actually " +
            Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments));
        Console.WriteLine();
 
        int msec = Environment.TickCount;
        Console.WriteLine("Windows has been running for " +
            msec + " milliseconds");
        Console.WriteLine("\tor " + msec / 3600000.0 + " hours");
        Console.WriteLine();
 
        Console.WriteLine("You are running " + Environment.OSVersion);
        Console.WriteLine("\tand .NET version " + Environment.Version);
        Console.WriteLine();
    }
}

Программа начинается с получения значения текущего каталога, ссылающегося на "Мои документы". Эта функция доступна через статический метод Environment.GetFolderPath, который возвращает строку. Аргумент является членом перечисления SpecialFolder, но перечисление SpecialFolder на самом деле определяется в классе Environment, которое является длинным именем члена Environment.SpecialFolder.MyDocuments.

Статическое свойство Environment.TickCount возвращает int, указывающее количество миллисекунд, которое текущая сессия окна была запущена. Один из вызовов WriteLine в программе отображает это значение напрямую, в то же время, другой делит его на 3600000,0, чтобы получить значение с плавающей точкой в часах.

Когда я запустил эту программу под Windows XP, первые две части программы отобразили следующую информацию:

Мои Документы на самом деле C:\Documents and Settings\Charles\My Documents
Windows has been running for 16729593 milliseconds
or 4.64710916666667 hours

Когда я запустил программу в Windows Vista, первый пункт отобразился в виде:

Мои Документы на самом деле H:\Users\Charles\Documents

Последняя часть программы содержит два статических свойства с именами Environment.OSVersion и Environment.Version. Свойство Version задокументировано, как возвращающее объект типа Version, который является классом, определяемым в пространстве имен System. Это может показаться немного странным, что свойство с именем Version возвращает объект типа Version, но такие именования являются довольно распространенными в .NET.

Класс Version (определенный в пространстве имен System) имеет четыре важных целочисленных свойства с именами Major, Minor, Build и Revision. Метод ToString, определённый классом Version, любезно отображает эти четыре числа, разделенные точками, как мы привыкли видеть в отображаемом номере версии.

Свойство Environment.OSVersion возвращает объект типа OperatingSystem. Важнейшие свойства класса OperatingSystem это – Platform (который является членом перечисления PlatformID), Version (который является объектом типа Version), и ServicePack – который имеет строковый тип. Опять же, метод ToString – безупречно передаёт эту информацию в удобном для чтения виде, поэтому последняя часть программы ShowEnvironmentStuff отображает информацию (когда я запустил её под Windows XP):

You are running Microsoft Windows NT 5.1.2600 Service Pack 2
and .NET version 2.0.50727.42

Под Windows Vista программа сообщила:

You are running Microsoft Windows NT 6.0.6000
and .NET version 2.0.50727.312

Если вы хотите несколько более явного определения объектов, возвращаемых из свойств OSVersion и Version, вы можете сделать следующее:

Version vers = Environment.Version;
OperatingSystem opsys = Environment.OSVersion;
Console.WriteLine("You are running " + opsys);
Console.WriteLine("\tand .NET version " + vers);

Здесь переменная vers объявлена как объект типа Version, а opsys объявлено как объект типа OperatingSystem, которые являются типами объектов, возвращаемых из Envionment.Version и Environment.OSVersion.

Изучение C# обычно начинается со статического метода Main и статических методов класса Console, но статические методы и свойства, как правило, скорее исключение, чем правило. В целом, программа имеет дело с экземплярами классов и структур.

Единственная причина, по которой Console полностью статическая потому, что к любому приложению, есть только одна консоль. Если бы приложение могло создавать несколько консолей, то класс Console имел бы конструктор, который возвращал экземпляр класса Console, и WriteLine был бы методом экземпляра. Вам бы пришлось предварять WriteLine одним из экземпляров класса Console, чтобы указать на какой консоли вы хотите отобразить текст.

Environment, так же, является коллекцией статических методов и свойств, потому что, в любом приложении, есть только одна среда операционной системы и одна машина, на которой оно работает. (Тем не менее, свойства Environment возвращают объекты других классов.)

В .NET 1.0, на самом деле можно было создавать экземпляры классов Console и Environment используя новое выражение вроде этого:

Console cons = new Console(); // Не работает больше.

Но это больше не работает. Console, и Environment не содержат ничего, кроме статических методов и свойств, так как определения классов и они сами содержат статическое ключевое слово:

public static class Console
{ ... }

Поскольку вы не можете создать экземпляр класса Console, вы не можете вызвать метод ToString из Console, потому что ToString всегда метод экземпляра.

Хотя структуры Int32 и Double, в первую очередь предназначены для работы с переменными int, и double, эти структуры также имеют некоторые статические члены. В частности, эти структуры имеют статический метод, называемый Parse, который используется для преобразования строк в числа.

Статическая метод Int32.Parse принимает строку в качестве аргумента и возвращает объект типа Int32. Метод Parse в значительной степени противоположность метода ToString. Как вы уже знаете, ToString является методом экземпляра, так как он относится к конкретному целому. Вы должны иметь целое – любая переменная или литерал или, возможно, возвращаемое значение метода – для вызова метода ToString из структуры Int32:

int i = 275;
string str = i.ToString();

Int32.Parse – статический метод. Вы можете использовать этот метод, поместив структуру Int32 слева от названия метода. Вам не нужно иметь целое число около вызова Int32.Parse. Метод сам создает целое число для Вас:

string str = "275";
int i = Int32.Parse(str);

Поскольку – int является псевдонимом для System.Int32, вы можете вызвать Parse так:

int i = int.Parse(str);

Хотя это совершенно правильно, уверен, выглядит это несколько странно. Я предпочитаю использовать реальный класс или имя структуры при вызове статических методов.

Структура System.Double так же имеет статический метод с именем Parse, и методы Parse в обеих структурах имеют перегрузки, которые принимают члены перечисления NumberStyles для управления входящими типами принимаемыми Parse.

Далее мы приводим программу, которая использует Double.Parse со статическим методом, из полностью статического класса Math, для вычисления степеней.

Exponentiation.cs

//-----------------------------------------------
// Exponentiation.cs (c) 2006 by Charles Petzold
//-----------------------------------------------
using System;
 
class Exponentiation
{
    static void Main()
    {
        Console.Write("Enter the base: ");
        double number = Double.Parse(Console.ReadLine());
 
        Console.Write("Enter the power: ");
        double power = Double.Parse(Console.ReadLine());
 
        Console.WriteLine(number + " to the " + power +
            " power equals " + Math.Pow(number, power));
    }
}

Обратите внимание, что в обоих случаях аргумент Double.Parse вызывает Console.ReadLine, который возвращает строку, которая затем передается в метод Parse.

Если вы наберете что-то с чем Parse не сможет справиться, вы получите исключение Format-Exception. Вы можете отловить это исключение, или вы можете использовать альтернативный метод, называемый TryParse, который не вызывает исключение при неправильном вводе. (Я опишу оба варианта в главе 12.)

Некоторые из общих классов и структур, определенных в .NET Framework определяют несколько версий метода ToString. Структура Double, например, определяет четыре различных метода ToString:

string ToString()
string ToString(string format)
string ToString(IFormatProvider provider)
string ToString(string format, IFormatProvider provider)

Вторая версия метода ToString позволяет использовать строку форматирования, которая состоит из буквы, возможно с последующим числом. Например, если num является переменной типа double, тогда:

num.ToString("F3");

отобразит num в стиле "с фиксированной точкой" с тремя знаками после запятой. Следующая программа демонстрирует некоторые из вариантов, которые есть у вас для отображения номера.

NumericFormatting.cs
//--------------------------------------------------
// NumericFormatting.cs (c) 2006 by Charles Petzold
//--------------------------------------------------
using System;
 
class NumericFormatting
{
    static void Main()
    {
        Console.WriteLine("Currency    C3: " + Math.PI.ToString("C3"));
        Console.WriteLine("Exponential E3: " + Math.PI.ToString("E3"));
        Console.WriteLine("Fixed-Point F3: " + Math.PI.ToString("F3"));
        Console.WriteLine("General     G3: " + Math.PI.ToString("G3"));
        Console.WriteLine("Number      N3: " + Math.PI.ToString("N3"));
        Console.WriteLine("Percent     P3: " + Math.PI.ToString("P3"));
        Console.WriteLine("Round-Trip  R3: " + Math.PI.ToString("R3"));
        Console.WriteLine();
        Console.WriteLine("Fixed-Point F3: " + 12345678.9.ToString("F3"));
        Console.WriteLine("General     G3: " + 12345678.9.ToString("G3"));
        Console.WriteLine("Number      N3: " + 12345678.9.ToString("N3"));
        Console.WriteLine();
        Console.WriteLine("Decimal     D3: " + 55.ToString("D3"));
        Console.WriteLine("General     G3: " + 55.ToString("G3"));
        Console.WriteLine("Hexadecimal X3: " + 55.ToString("X3"));
    }
}

 

Первые семь выражений отобразят π, а следующие результаты появляются, когда вы запустите эту программу в системе с региональными настройками США:

Currency    C3: 3,142р.
Exponential E3: 3,142E+000
Fixed-Point F3: 3,142
General     G3: 3,14
Number      N3: 3,142
Percent     P3: 314,159%
Round-Trip  R3: 3,1415926535897931

Во многих случаях, число которое вы подставляете в строку форматирования, указывает на число знаков после запятой. Исключением является общее (General) форматирование – в этом случае, число обозначает общее количество цифр. Общее форматирование будет использовать либо экспоненциальное, либо форматирование с фиксированной точкой, в зависимости от того, какое из них наиболее экономично для конкретного числа. Если вы используете версию ToString без параметров, это эквивалентно "G".

Как вы можете видеть, форматирование Round-Trip (двойной проход) игнорирует номер в строке форматирования, и создает строку, которая может быть передана в Parse, для получения первоначального номера.

Следующие три выражения в программе показывают, что происходит с рядом больших цифр слева от десятичной точки:

Fixed-Point F3: 12345678,900
General     G3: 1,23E+07
Number      N3: 12 345 678,900 

В этом случае, общее форматирование использует экспоненциальный формат, потому что, это более экономично. Форматирование строк Number (Числовое форматирование) вставляет запятые (или то, что в текущем регионе используется), в качестве разделителей тысяч.

Два параметра форматирования – Decimal (десятичное) и Hexadecimal (шестнадцатеричное) – предназначены для использования только с целыми числами. Оба вставляют нули в левую часть значения, если необходимо, отобразить число такого размера, количество символов которого вы указали в строке форматирования:

Decimal     D3: 055
General     G3: 55
Hexadecimal X3: 037

Если вы измените число следующего за D или X на 1, вы, вероятно, будете рады заметить, что никакие фактические цифры не удаляются из результата.

Если вы перейдёте в панель управления и вызовете апплет "Язык и региональные стандарты", вы сможете изменить некоторые параметры – например, символ валюты и разделитель тысяч – которые влияют на то, как ToString отображает номер. По умолчанию, метод ToString использует региональные настройки, но это поведение может быть, в некоторых случаях, нежелательным. Вы можете отобразить валюту в долларах или евро, независимо от региональных настроек пользователя.

Эта опция стала возможным благодаря третьей и четвертой перегрузке метода ToString, которые имеют следующий синтаксис:

string ToString(IFormatProvider provider)
string ToString(string format, IFormatProvider provider)

Если вы посмотрите в документацию пространства имен System, вы найдёте IFormatProvider – идентифицируемый как интерфейс. (В соответствии с соглашением, все интерфейсы в .NET Framework начинаются с заглавной буквы I.)  Вы также увидите, что IFormatProvider имеет один метод, который называется – GetFormat.

Интерфейсы сами по себе не содержат никакого кода. Где-то в исходном коде для .NET Framework, IFormatProvider, вероятно, определяется в полном объеме, например так:

public interface IFormatProvider { object GetFormat(Type formatType); }

То, что на самом деле должно быть передано методу ToString, находится в экземпляре класса, реализующего интерфейс IFormatProvider, и поэтому, это означает, что класс содержащий метод GetFormat определён так же, как и сигнатура в IFormatProvider, но при этом имеет реальный код.

Для работы числового форматирования, соответствующий класс, который реализует интерфейс IFormatProvider, называется NumberFormatInfo, который определён в пространстве имен System.Globalization. Для ссылки на класс NumberFormatInfo, в вашей программе вы должны предварить имя класса – System.Globalization, или использовать директиву using для System.Globalization. (Я предпочитаю, последний вариант.)

Чтобы настроить форматирование чисел ToString, необходим экземпляр класса NumberFormatInfo. Если вы посмотрите на свойства этого класса, вы увидите такие вещи, как CurrencySymbol, CurrencyDecimal-Separator, и PercentSymbol. Все эти свойства являются "записываемыми" и "читаемыми". Это означает, что вы можете создать объект типа NumberFormatInfo, установить свойства, которые вы хотите, а затем передать этот объект в ToString, для того чтобы получить желаемый результат.

Вы можете создать объект типа NumberFormatInfo с помощью конструктора с минимальными параметрами, определенного классом:

NumberFormatInfo info = new NumberFormatInfo();

Вы можете установить некоторые свойства таким образом:

info.CurrencySymbol = "\x20AC";
info.CurrencyPositivePattern = 3;
info.CurrencyNegativePattern = 8;

Значение Юникода 0x20AC является символом евро. Если вы посмотрите в документацию CurrencyPositivePattern, вы увидите, что параметр равный 3 определяет, что символ валюты должен быть показан после номера отделённый пробелом. В CurrencyNegativePattern параметр 8 означает, что символ появится в том же месте и для отрицательных чисел, а отрицательный знак появится перед номером.

Есть и другие способы получить экземпляры класса NumberFormatInfo без явного использования конструктора. Класс NumberFormatInfo имеет два статических метода, называемые – CurrentInfo и InvariantInfo, которые возвращают экземпляры класса NumberFormatInfo.

Это может показаться немного странным, что статические методы класса возвращают экземпляры класса, но это совершенно легально. Вот как может выглядеть синтаксис:

NumberFormatInfo info = NumberFormatInfo.CurrentInfo;

CurrentInfo является статическим свойством класса NumberFormatInfo, поэтому оно должно быть предварено именем класса. Это свойство – только для чтения, и оно возвращает объект типа NumberFormatInfo, которые затем можно сохранить в переменной типа NumberFormatInfo. Код свойства CurrentInfo, очевидно, вызывает конструктор NumberFormatInfo, чтобы создать экземпляр класса. Затем он устанавливает целую группу свойств объекта.

Статическое свойство NumberFormatInfo.CurrentInfo возвращает объект NumberFormatInfo с настройками, которые применимы для вашего региона, который вы указали в панели управления.

Кроме того, статическое свойство NumberFormatInfo.InvariantInfo возвращает экземпляр NumberFormatInfo инициализированную "инвариантными" настройками, то есть с параметрами, которые не зависят от какой-либо конкретной культуры, и которые будут одинаковыми, независимо от машины, на которой запущена программа.

Конструктор NumberFormatInfo создает экземпляр NumberFormatInfo инициализированный инвариантной информацией. Вполне вероятно, что статическое свойство NumberFormatInfo.InvariantInfo осуществляется с помощью простого вызова конструктора.

Если вы хотите вызвать ToString с объектом типа NumberFormatInfo, можно просто передать NumberFormatInfo.InvariantInfo или NumberFormatInfo.CurrentInfo непосредственно к методу ToString. (Если вы используете простую форму ToString, NumberFormatInfo.CurrentInfo используется по умолчанию).

Следующая программа выводит число в денежном формате при помощи NumberFormatInfo.InvarientInfo (который использует символ валюты – #), NumberFormatInfo.CurrentInfo (который будет использовать тот символ валюты, который вы указали в панели управления), и специальной версии, которая отображает символ Евро (который, к сожалению, не показывается на консоли и появляется в виде знака вопроса).

CurrencyFormatting.cs

//---------------------------------------------------
// CurrencyFormatting.cs (c) 2006 by Charles Petzold
//---------------------------------------------------
using System;
using System.Globalization;
 
class CurrencyFormatting
{
    static void Main()
    {
        double money = 1234567.89;
        Console.WriteLine("InvariantInfo: " +
            money.ToString("C", NumberFormatInfo.InvariantInfo));
        Console.WriteLine("CurrentInfo: " +
            money.ToString("C", NumberFormatInfo.CurrentInfo));
        NumberFormatInfo info = new NumberFormatInfo();
        info.CurrencySymbol = "\x20AC";
        info.CurrencyPositivePattern = 3;
        info.CurrencyNegativePattern = 8;
        Console.WriteLine("Custom Info: " + money.ToString("C", info));
    }
}

Обратите внимание, на директиву using для пространства имен System.Globalization.

Я знаю, что вы очень-очень хотите увидеть символ Евро, так давайте поставим эту простую логику в небольшую Windows Forms программу. Для следующего проекта, вы должны будете добавить ссылку на System.Windows.Forms.dll.

CurrencyFormattingMessageBox.cs

//-------------------------------------------------------------
// CurrencyFormattingMessageBox.cs (c) 2006 by Charles Petzold
//-------------------------------------------------------------
using System;
using System.Globalization;
using System.Windows.Forms;
class CurrencyFormatting
{
    static void Main()
    {
        double money = 1234567.89;
        string strDisplay;
 
        strDisplay = "InvariantInfo: " +
            money.ToString("C", NumberFormatInfo.InvariantInfo) +
            Environment.NewLine;
 
        strDisplay += "CurrentInfo: " +
            money.ToString("C", NumberFormatInfo.CurrentInfo) +
            Environment.NewLine;
 
        NumberFormatInfo info = new NumberFormatInfo();
        info.CurrencySymbol = "\x20AC";
        info.CurrencyPositivePattern = 3;
        info.CurrencyNegativePattern = 8;
 
        strDisplay += "Custom Info: " + money.ToString("C", info);
 
        MessageBox.Show(strDisplay, "Currency Formatting");
    }
}

Обратите внимание, что используется директива using для System.Windows.Forms. В этой программе, переменная strDisplay появляется три раза слева назначения и соединение выражений присваивания, и становится первым аргументом в статическом методе MessageBox.Show.

ToString, конечно, мощный инструмент для форматирования. Но в общей практике используется несколько иной подход, который очень похож на функцию printf в С и С++. Первый аргумент в Console.WriteLine является строкой форматирования, а последующие аргументы являются значениями, которые будут подставлены. Например:

Console.WriteLine("{0} times {1} equals {2}", A, B, A * B);

В строке форматирования, номера, окруженные фигурными скобками это – метки-заполнители. Номера соответствуют последующим аргументам, где 0 – является первым из последующих аргументов, 1 – вторым и так далее. Цифры заполнители в строке форматирования не обязательно должны идти по возрастанию:

Console.WriteLine("{2} equals {0} times {1}", A, B, A * B);

Вы можете повторить определенное количество заполнителей:

Console.WriteLine("{0} times {0} equals {1}", A, A * A);

Вы можете пропустить часть заполнителей. В следующем примере, переменные C, D и Е, игнорируются и не отображаются:

Console.WriteLine("{1} times {2} equals {4}", C, A, B, D, A * B, E);

Единственное ограничение в том, что число аргументов должно быть больше, чем наибольшее количество заполнителей.

Если вам нужно вывести фигурные скобки в строке форматирования, используйте фигурные скобки: {{или}} будут интерпретироваться как символ для отображения.

Для управления форматом отдельных аргументов, вы должны сопроводить номер заполнителя двоеточием и строкой форматирования аналогичной той, которые Вы передавали методу ToString:

Console.WriteLine("{0:N2} times {1:N2} equals {2:N4}", A, B, A * B);

В принципе, это выражение эквивалентно следующему:

Console.WriteLine(A.ToString("N2") + " times " + B.ToString("N2") +
" equals " + (A * B).ToString("N4"));

Вы также можете контролировать величину поля, необходимого для строки, возвращаемой из ToString. Вы можете сделать это, дополнив число-заполнитель запятой и шириной поля в символах:

Console.WriteLine("{0,5:N2} times {1,5:N2} equals {2,10:N4}", A, B, A * B);

То, что вы только-что указали это – минимальная ширина поля. Метод не будет обрезать результат ToString. В этом примере, А и В будут отображаться в области минимальный размер которой – 5 символов в ширину, а итог в – 10 символов. Число выравнивается по правому краю используя пробелы, чтобы дополнить левую часть. Для выравнивания по левому краю, используйте отрицательную ширину поля:

Console.WriteLine("{0,-5:N2} times {1,-5:N2} equals {2,-10:N4}", A, B, A * B);

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

Как вы увидели, методы ToString отдельных классов и структур отвечают за большую часть работы по форматированию. Всё остальное, на самом деле, не обрабатывается в Console.WriteLine. При использовании форматирования строк, Console.WriteLine просто поручает работу к другому статическому методу String.Format. Если Console.WriteLine является C# версией Printf, то String.Format – C# версией Sprintf.

Таким образом, даже если вы никогда больше не напишете консольную программу в оставшейся части вашей жизни, вы, вероятно, будет по-прежнему использовать String.Format для форматирования объектов при отображении.


© Charles Petzold ".NET Book Zero" 2007