Tostring c что это
Все классы в .NET, даже те, которые мы сами создаем, а также базовые типы, такие как System.Int32 , являются неявно производными от класса Object. Даже если мы не указываем класс Object в качестве базового, по умолчанию неявно класс Object все равно стоит на вершине иерархии наследования. Поэтому все типы и классы могут реализовать те методы, которые определены в классе System.Object. Рассмотрим эти методы.
ToString
Метод ToString служит для получения строкового представления данного объекта. Для базовых типов просто будет выводиться их строковое значение:
Для классов же этот метод выводит полное название класса с указанием пространства имен, в котором определен этот класс. И мы можем переопределить данный метод. Посмотрим на примере:
Для переопределения метода ToString() в классе Clock, который представляет часы, используется ключевое слово override (как и при обычном переопределении виртуальных или абстрактных методов). В данном случае метод ToString() выводит в строке значения свойств Hours, Minutes, Seconds.
Класс Person не переопределяет метод ToString, поэтому для этого класса срабатывает стандартная реализация этого метода, которая выводит просто название класса.
Кстати в данном случае мы могли задействовать обе реализации:
То есть если имя — свойство Name не имеет значения, оно представляет пустую строку, то возвращается базовая реализация — название класса. Стоит отметить, что базовая реализация возвращает не просто строку, а объект string? — то есть это может быть строка string, либо значение null , которое указывает на отсутствие значения. И в реальности в качестве возвращаемого типа для метода мы можем использовать как string , так и string?
Если же имя у объекта Person установлено, то возвращается значение свойства Name. Для проверки строки на наличие значения применяется метод String.IsNullOrEmpty() .
Стоит отметить, что различные технологии на платформе .NET активно используют метод ToString для разных целей. В частности, тот же метод Console.WriteLine() по умолчанию выводит именно строковое представление объекта. Поэтому, если нам надо вывести строковое представление объекта на консоль, то при передаче объекта в метод Console.WriteLine необязательно использовать метод ToString() — он вызывается неявно:
Метод GetHashCode
Метод GetHashCode позволяет возвратить некоторое числовое значение, которое будет соответствовать данному объекту или его хэш-код. По данному числу, например, можно сравнивать объекты. Можно определять самые разные алгоритмы генерации подобного числа или взять реализаци базового типа:
В данном случае метод GetHashCode возвращает хеш-код для значения свойства Name. То есть два объекта Person, которые имеют одно и то же имя, будут возвращать один и тот же хеш-код. Однако в реальности алгоритм может быть самым различным.
Получение типа объекта и метод GetType
Метод GetType позволяет получить тип данного объекта:
Этот метод возвращает объект Type , то есть тип объекта.
С помощью ключевого слова typeof мы получаем тип класса и сравниваем его с типом объекта. И если этот объект представляет тип Person, то выполняем определенные действия.
Причем поскольку класс Object является базовым типом для всех классов, то мы можем переменной типа object присвоить объект любого типа. Однако для этой переменной метод GetType все равно вернет тот тип, на объект которого ссылается переменная. То есть в данном случае объект типа Person.
Стоит отметить, что проверку типа в примере выше можно сократить с помощью оператора is :
В отличие от методов ToString, Equals, GetHashCode метод GetType() не переопределяется.
Метод Equals
Метод Equals позволяет сравнить два объекта на равенство. В качестве параметра он принимает объект для сравнения в виде типа object и возврашает true , если оба объекта равны:
Например, реализуем данный метод в классе Person:
Метод Equals принимает в качестве параметра объект любого типа, который мы затем приводим к текущему классу — классу Person.
Если переданный объект представляет тип Person, то возвращаем результат сравнения имен двух объектов Person. Если же объект представляет другой тип, то возвращается false.
В данном случае для примера применяется довольно простой алгоритм сравнения, однако при необходимости реализацию метода можно сделать более сложной, например, сравнивать по нескольким свойствам при их наличии.
Стоит отметить, что вместе с методом Equals следует реализовать метод GetHashCode.
И если следует сравнивать два сложных объекта, как в данном случае, то лучше использовать метод Equals, а не стандартную операцию ==.
ToString Method in C#
Representing data as strings is an inbuilt feature of the C# language and is a common operation in applications. In this article, we are going to learn how we can use the ToString() method in C# through an example.
What Is ToString() Method in C#?
This is a method that returns the string values of an object in C#. We may also need to format data in a specific way, and this method helps us accomplish that.
To demonstrate its usage, let’s create a console application first.
After that, we create a new Person class:
Here, we define the class and then initialize the three class properties in the constructor.
Let’s now instantiate the class and call the ToString() method:
By default, ToString() does not take any parameters. When we print the results of the method call to the console, we get the namespace of the Person class:
What we have covered is only the basic usage of the ToString() method. But this method can do much more than that.
So how can we customize the ToString() method to suit our needs?
Overriding the ToString() Method
When working with objects, we may want to explicitly define how the object data should appear. In this case, we define our own implementation of the ToString() method.
Working with our Person class, for instance, we may want to view the values of the class properties as well.
To accomplish this, we override the ToString() method:
We interpolate the properties of the class and return a string representing the object values.
This is just a simple demonstration of what the ToString() method can do.
Overloading the ToString() Method
The default method does not take any parameters. However, depending on the data, we may want to pass additional parameters that dictate the format.
To demonstrate overloading, let’s create a new Car class:
After that, let’s create an instance of the class:
var car = new Car(«Tesla», «Model S», 100000M, DateTime.Now);
Here, we pass the values of the object during instantiation.
To do this, we can overload ToString() by passing an additional culture parameter:
In this case, we use culture to format the value of Price as currency.
Calling the overloaded method:
We use the «en-US» culture because we want to format the price in US Dollars.
Printing the result, we get:
Tesla Model S costs $100,000.00 and was sold on 12/2/2022 5:10:56 PM
Formatting Dates
In the same way, we may want to use custom DateTime formatting for the SoldAt property of the class. For this, we pass one more additional parameter to the ToString() method:
When calling this method, we also specify the format in which we want the date to be:
Printing the results, we get:
Tesla Model S costs $100,000.00 and was sold on 02-Dec-2022
Also, depending on the format we pass as the argument, we will get a different date format.
Conclusion
In this article, we have learned how to use the ToString() method in C#. Beyond the basic usage, we have demonstrated overloading and overriding the method.
We can apply what we have learned across the different types supported by the C# language.
Why does the string type have a .ToString() method?
Why does the string data type have a .ToString() method?
![]()
6 Answers 6
The type System.String , like almost all types in .NET, derives from System.Object . Object has a ToString() method and so String inherits this method. It is a virtual method and String overrides it to return a reference to itself rather than using the default implementation which is to return the name of the type.
From Reflector, this is the implementation of ToString in Object :
And this is the override in String :
As Mark points out, it’s just returning a reference to itself. But, why is this important? All basic types should return a string representation of themselves. Imagine a logging function that worked like this:
This allows you to pass any basic type and log it’s contents. Without string returning itself, it would simply print out «String» rather than it’s contents. You could also do the same thing with a template function.
Think this is silly? That’s basically what the string formatting functions do. It calls «ToString» when you do this:
String is an object, it is not a data type. Because String is an object, it inherits from the Root Object the ToString() method.
Классы и объекты C#: класс System.Object
Абсолютно все классы в .NET и C#, в частности, включая и те, которые мы создаем самостоятельно, а равно и базовые типы данных, такие как System.Int32 , System.Double и так далее, неявно являются наследниками класса Object . В любом случае, даже если при создании своего класса мы не указываем класс Object в качестве родительского, то неявно по умолчанию класс Object стоит на вершине иерархии наследования. Исходя из этого, все типы данных и классы могут реализовать методы, определенные в классе System.Object . Рассмотрим методы класса Object более подробно.
Метод ToString в C#
Метод ToString() возвращает строковое представление объекта. Так, для базовых типов метод вернет их строковое значение, например:
В случае использования метода ToString() для классов, метод выведет полное название класса с указанием пространства имен, в котором этот класс был определен. Метод является виртуальным ( virtual ), поэтому мы можем его переопределить. Например:
В представленном примере в классе Clock метод ToString() переопределен, поэтому в консоль будет выведено не название класса, а время, которое мы задаем при инициализации объекта. При этом, мы можем, как обычно при переопределении методов, пользоваться как собственной реализацией метода ToString() в класса-наследнике, так и базовой версией, используя ключевое слово base . Например:
Если свойство Name не будет задано, то в результате вызова метода ToString() будет использована базовая версия и метод вернет имя класса. Для проверки свойства на пустоту при этом используется метод строк IsNullOrEmpty() .
Различные технологии на платформе .NET активно используют метод ToString для разных целей. В частности, тот же метод Console.WriteLine() по умолчанию выводит именно строковое представление объекта. Поэтому, если нам надо вывести строковое представление объекта на консоль, то при передаче объекта в метод Console.WriteLine необязательно использовать метод ToString() — он вызывается неявно:
Метод GetHashCode в C#
Метод GetHashCode() позволяет возвратить некоторое числовое значение, соответствующее объекту или, как ещё говорят, его хэш-код. По этому числу можно, например, сравнивать объекты между собой, сортировать их и т.д.. Мы можем определять различные алгоритмы генерации хэш-кожа или же взять реализацию из базового типа:
В приведенном выше примере метод GetHashCode() возвращает хеш-код для свойства Name . Поэтому, если два объекта Person будут иметь одно и то же значение свойства Name , то они будут возвращать один и тот же хеш-код.
Метод Equals в C#
По умолчанию Equals() проверяет два объекта на равенство, используя для этого ссылки на объект. Однако, мы можем переопределить метод Equals() , что позволяет проверить два объекта на равенство, используя собственный алгоритм сравнения. Например:
Метод Equals() принимает в качестве параметра объект любого типа, который мы приводим к текущему, если они являются объектами одного класса. Затем сравниваем по именам. Если имена равны, возвращаем true , что будет говорить, что объекты равны. Однако при необходимости реализацию метода можно сделать более сложной, например, сравнивать по нескольким свойствам при их наличии.
Если необходимо сравнивать два сложных объекта, как в примере выше, то лучше использовать метод Equals() , а не стандартную операцию == .
Метод ReferenceEquals в C#
В отличие от Equals() , этот метод не переопределяется и использует для сравнения двух объектов ссылки на эти объекты.
Метод GetType и получение типа объекта в C#
Метод GetType() позволяет получить тип объекта. Например:
Метод возвращает объект Type (тип объекта). С помощью ключевого слова typeof мы получаем тип класса и сравниваем его с типом объекта. И если этот объект представляет тип Person , то выполняем определенные действия.
Причем поскольку класс Object является базовым типом для всех классов, то мы можем переменной типа object присвоить объект любого типа. Однако для этой переменной метод GetType() все равно вернет тот тип, на объект которого ссылается переменная . То есть в данном случае объект типа Person .
В отличие от методов ToString() , Equals() , GetHashCode() метод GetType() не виртуальные и не может быть переопределен.
Отличие методов Equals() и ReferenceEquals()
Следует отметить некоторые различия в методах Equals() и ReferenceEquals() .
Во-первых, несмотря на то, что оба этих метода по умолчанию действуют одинаково — сравнивают два объекта по ссылкам, тем не менее, так как Equals() может переопределяться в наследниках, то этот метод часто используется в классах-наследниках для сравнения двух объектов именно по значению полей, как было показано выше.
Во-вторых, механизм работы Equals() и ReferenceEquals() различается в зависимости от типа данных. Это различие наглядно показано в следующем примере:
Здесь мы сравнили число типа int само с собой и ReferenceEquals() почему-то выдал результат False . Происходит это по следующей причине: п ри сравнении типов значений. они упаковываются перед передачей в ReferenceEquals() и, в итоге, сравниваются не сами значения, а ссылки на полученные объекты, которые оказываются различными. Соответственно, Equals() действует иначе — е сли текущий экземпляр является типом значения, то Equals() проверяет равенство значений. Равенство значений означает, что д ва объекта имеют один и тот же тип. То есть, в следующем примере два целых числа не будут равны при использовании Equals() так как они относятся к разным типам данных:
Что использовать для сравнения — Equals() , ReferenceEquals() или == зависит от конкретных задач, но можно предложить следующее:
- для типов значений:
- если требуется сравнивать значения без учёта типа данных, то используем ==
- если требуется сравнивать значения с учётом типа данных — используем Equals()
- для ссылочных типов:
- если необходимо определить равенство двух объектов по значениям его полей — используем переопределенную версию Equals()
- если необходимо определить то, что две переменные ссылочного типа ссылаются на один и тот же объект в памяти — используем ReferenceEquals()
Итого
Сегодня мы рассмотрели основные методы класса Object — родителя для всех классов в C#. Часть методов этого класса являются виртуальными, что позволяет их переопределять в классах-наследниках и реализовать, например, свою логику сравнения двух объектов. Также рассмотрены различия двух похожих методов Equals() и ReferenceEquals() и предложен алгоритм использования того или иного метода в зависимости от типа данных переменной.