Практическое руководство. Переопределение метода ToString (руководство по программированию на C#)
Каждый класс или структура в языке C# неявно наследует класс Object. Поэтому каждый объект в языке C# получает метод ToString, который возвращает строковое представление данного объекта. Например, все переменные типа int имеют метод ToString , который позволяет им возвращать их содержимое в виде строки:
int x = 42; string strx = x.ToString(); Console.WriteLine(strx); // Output: // 42
При создании пользовательского класса или структуры необходимо переопределить метод ToString, чтобы передать информацию о типе клиентскому коду.
Дополнительные сведения об использовании строк форматирования и других типов пользовательского форматирования с методом ToString см. в разделе Типы форматирования.
При принятии решения относительно того, какая информация должна будет предоставляться посредством этого метода, подумайте, будет ли создаваемый класс или структура когда-либо использоваться ненадежным кодом. Постарайтесь не предоставлять информацию, которая может быть использована вредоносным кодом.
Чтобы переопределить метод ToString в классе или структуре, выполните указанные ниже действия.
-
Объявите метод ToString со следующими модификаторами и типом возвращаемого значения:
public override string ToString()<>
class Person < public string Name < get; set; >public int Age < get; set; >public override string ToString() < return "Person: " + Name + " " + Age; >>
Метод ToString можно проверить с помощью показанного ниже кода.
Person person = new Person < Name = "John", Age = 12 >; Console.WriteLine(person); // Output: // Person: John 12
См. также
- IFormattable
- Руководство по программированию на C#
- Система типов C#
- Строки
- string
- override
- virtual
- Типы форматирования
Совместная работа с нами на GitHub
Источник этого содержимого можно найти на GitHub, где также можно создавать и просматривать проблемы и запросы на вытягивание. Дополнительные сведения см. в нашем руководстве для участников.
Класс Object

В C# предусмотрен специальный класс object, который неявно считается базовым классом для всех остальных классов и типов, включая и типы значений. Иными словами, все остальные типы являются производными от object. Это, в частности, означает, что переменная ссылочного типа object может ссылаться на объект любого другого типа. Кроме того, переменная типа object может ссылаться на любой массив, поскольку в C# массивы реализуются как объекты. Формально имя object считается в C# еще одним обозначением класса System.Object, входящего в библиотеку классов для среды .NET Framework.
Практическое значение этого в том, что помимо методов и свойств, которые вы определяете, также появляется доступ к множеству общедоступных и защищенных методов-членов, которые определены в классе Object. Эти методы присутствуют во всех определяемых классах.
Методы System.Object
Ниже перечислены все методы данного класса:
ToString()
Метод ToString() возвращает символьную строку, содержащую описание того объекта, для которого он вызывается. Кроме того, метод ToString() автоматически вызывается при выводе содержимого объекта с помощью метода WriteLine(). Этот метод переопределяется во многих классах, что позволяет приспосабливать описание к конкретным типам объектов, создаваемых в этих классах.
Применяйте этот метод, когда нужно получить представление о содержимом объекта — возможно, в целях отладки. Он предлагает очень ограниченные средства форматирования данных. Например, даты в принципе могут быть отображены в огромном разнообразии форматов, но DateTime.ToString() не оставляет никакого выбора в этом отношении. Если нужно более сложное строковое представление, которое, например, принимает во внимание установленные предпочтения или местные стандарты, то понадобится реализовать интерфейс IFormattable.
GetHashCode()
Этот метод используется, когда объект помещается в структуру данных, известную как карта (map), которая также называется хеш-таблицей или словарем. Применяется классами, которые манипулируют этими структурами, чтобы определить, куда именно в структуру должен быть помещен объект. Если вы намерены использовать свой класс как ключ словаря, то должны переопределить GetHashCode(). Существуют достаточно строгие требования относительно того, как нужно реализовывать перегрузку.
Хеш-код можно использовать в любом алгоритме, где хеширование применяется в качестве средства доступа к хранимым объектам. Следует, однако, иметь в виду, что стандартная реализация метода GetHashCode() не пригодна на все случаи применения.
Equals() и ReferenceEquals()
По умолчанию метод Equals (object) определяет, ссылается ли вызывающий объект на тот же самый объект, что и объект, указываемый в качестве аргумента этого метода, т.е. он определяет, являются ли обе ссылки одинаковыми. Метод Equals (object) возвращает логическое значение true, если сравниваемые объекты одинаковы, в противном случае — логическое значение false. Он может быть также переопределен в создаваемых классах. Это позволяет выяснить, что же означает равенство объектов для создаваемого класса. Например, метод Equals (object) можно определить таким образом, чтобы в нем сравнивалось содержимое двух объектов.
Как несложно догадаться, учитывая существование трех различных методов сравнения объектов, среда .NET использует довольно сложную схему определения эквивалентности объектов. Следует учитывать и использовать тонкие различия между этими тремя методами и операцией сравнения ==. Кроме того, также существуют ограничения, регламентирующие, как следует переопределять виртуальную версию Equals() с одним параметром, если вы решитесь на это — поскольку некоторые базовые классы из пространства имен System.Collections вызывают этот метод и ожидают от него определенного поведения.
Finalize()
Назначение этого метода в C# примерно соответствует деструкторам С++, и он вызывается при сборке мусора для очистки ресурсов, занятых ссылочным объектом. Реализация Finalize() из Object на самом деле ничего не делает и игнорируется сборщиком мусора. Обычно переопределять Finalize() необходимо, если объект владеет неуправляемыми ресурсами, которые нужно освободить при его уничтожении. Сборщик мусора не может сделать это напрямую, потому что он знает только об управляемых ресурсах, поэтому полагается на финализацию, определенную вами.
GetType()
Этот метод возвращает экземпляр класса, унаследованный от System.Type. Этот объект может предоставить большой объем информации о классе, членом которого является ваш объект, включая базовый тип, методы, свойства и т.п. System.Type также представляет собой стартовую точку технологии рефлексии .NET.
Clone()
Этот метод создает копию объекта и возвращает ссылку на эту копию (а в случае типа значения — ссылку на упаковку). Отметим, что при этом выполняется неглубокое копирование, т.е. копируются все типы значений в классе. Если же класс включает в себя члены ссылочных типов, то копируются только ссылки, а не объекты, на которые они указывают. Этот метод является защищенным, а потому не может вызываться для копирования внешних объектов. К тому же он не виртуальный, а потому переопределять его реализацию нельзя.
Давайте рассмотрим применение некоторых из этих методов на конкретном примере:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication1 < class Program < static void Main(string[] args) < var m = Environment.Version; Console.WriteLine("Тип m: "+m.GetType()); string s = m.ToString(); Console.WriteLine("Моя версия .NET Framework: " + s); Version v = (Version)m.Clone(); Console.WriteLine("Значение переменной v: "+v); Console.ReadLine(); >> >
Number.prototype.toString()
Метод toString() возвращает строковое представление указанного объекта Number .
Синтаксис
numObj.toString([radix])
Параметры
Необязательный параметр. Целое число между 2 и 36, определяющее основание системы счисления, используемой для представления числового значения.
Выбрасываемые исключения
Если в метод toString() передано основание не в диапазоне от 2 до 36, будет выброшено исключение RangeError .
Описание
Объект Number переопределяет метод toString , унаследованный из объекта Object ; он не наследует метод Object.prototype.toString . Для объектов Number метод toString() возвращает строку, представляющую объект в определённой системе счисления.
Метод toString() разбирает свой первый аргумент и пытается вернуть строковое представление в системе счисления с указанным основанием. Для оснований, больших 10, при обозначении цифр, больших 9, используются буквы латинского алфавита. Например, для шестнадцатеричных чисел (основание 16), используются буквы с a по f .
Если параметр radix не указан, предпочитаемое основание предполагается равным 10.
Если число numObj отрицательно, его знак сохраняется. Это правило действует даже если основание равно 2; возвращённая строка является двоичным представлением положительного числа numObj , перед которым ставится знак — , а не дополнительным кодом числа numObj .
Примеры
Пример: использование toString
var count = 10; console.log(count.toString()); // Выведет '10' console.log((17).toString()); // Выведет '17' var x = 6; console.log(x.toString(2)); // Выведет '110' console.log((254).toString(16)); // Выведет 'fe' console.log((-10).toString(2)); // Выведет '-1010' console.log((-0xff).toString(2)); // Выведет '-11111111'
Спецификации
| Specification |
|---|
| ECMAScript Language Specification # sec-number.prototype.tostring |
Совместимость с браузерами
BCD tables only load in the browser
Смотрите также
- Number.prototype.toFixed()
- Number.prototype.toExponential()
- Number.prototype.toPrecision()
Found a content problem with this page?
- Edit the page on GitHub.
- Report the content issue.
- View the source on GitHub.
This page was last modified on 7 авг. 2023 г. by MDN contributors.
Your blueprint for a better internet.
В чём разница между Convert.ToString(), ToString() и (String)?
Функция ToString() (вы забыли скобки) — это не приведение типов, это просто функция, которая для числа даёт его строковое представление.
Функция Convert.ToString(int) — это тоже не приведение типов, а функция, которая для числа даёт его строковое представление.
Обе функции ToString() и Convert.ToString() выдают строковое представление в текущей локали, так что различий быть не должно.
Приведение типов в ваших примерах лишь одно:
String c = (String)temp;
Это приведение типов не будет работать, т. к. temp имеет реальный тип int , а не string . Это даже не скомпилируется, т. к. компилятор видит, что число типа int никаким образом не может быть строкой. Приведение типов не меняет сам объект, оно просто меняет тип ссылки на настоящий тип объекта или какой-то из его базовых типов. (Вы ведь понимаете, что число 123 — это совсем не то же самое, что строка из трёх символов ‘1’, ‘2’ и ‘3’?)
Уголок зануды пуриста.
Вызовы 5.ToString() и Convert.ToString(5) , согласно sourceof.net, являются вызовами
Number.FormatInt32(5, null, NumberFormatInfo.GetInstance(Thread.CurrentThread.CurrentCulture))
Number.FormatInt32(i, null, NumberFormatInfo.CurrentInfo)
внутреннего класса Number соответственно. Могут ли NumberFormatInfo.GetInstance(Thread.CurrentThread.CurrentCulture) и NumberFormatInfo.CurrentInfo не совпадать?
Код NumberFormatInfo.GetInstance для нашего случая можно упростить до следующего:
if (!cultureInfo.m_isInherited) return cultureInfo.numInfo ?? cultureInfo.NumberFormat; return cultureInfo.GetFormat(typeof(NumberFormatInfo)) as NumberFormatInfo ?? CurrentInfo;
А код NumberFormatInfo.CurrentInfo — до
CultureInfo cultureInfo = Thread.CurrentThread.CurrentCulture; if (!cultureInfo.m_isInherited && cultureInfo.numInfo != null) return cultureInfo.numInfo; return ((NumberFormatInfo)cultureInfo.GetFormat(typeof(NumberFormatInfo)));
В случае, когда cultureInfo.m_isInherited == false (то есть, у нас CultureInfo , а не производный от него тип), у нас cultureInfo.GetFormat(typeof(NumberFormatInfo)) возвращает NumberFormat , так что различий нет.
В случае же, когда у нас не CultureInfo , а производный от него тип, у нас код упрощается до
cultureInfo.GetFormat(typeof(NumberFormatInfo)) as NumberFormatInfo ?? CurrentInfo;
((NumberFormatInfo)cultureInfo.GetFormat(typeof(NumberFormatInfo)));
Разный результат может быть лишь в случае, если переопределённая виртуальная функция GetFormat сошла с ума, и возвращает разные типы при разных вызовах.
class WeirdCultureInfo : CultureInfo < public WeirdCultureInfo() : base("en-US") < >bool flag = false; public override object GetFormat(Type formatType) < object result = flag ? (object)DateTimeFormat : NumberFormat; flag = true; return result; >>