Класс System.Object и его методы

Последнее обновление: 29.12.2021

Все классы в .NET, даже те, которые мы сами создаем, а также базовые типы, такие как System.Int32, являются неявно производными от класса Object. Даже если мы не указываем класс Object в качестве базового, по умолчанию неявно класс Object все равно стоит на вершине иерархии наследования. Поэтому все типы и классы могут реализовать те методы, которые определены в классе System.Object. Рассмотрим эти методы.

ToString

Метод ToString служит для получения строкового представления данного объекта. Для базовых типов просто будет выводиться их строковое значение:

int i = 5;
Console.WriteLine(i.ToString()); // выведет число 5

double d = 3.5;
Console.WriteLine(d.ToString()); // выведет число 3,5

Для классов же этот метод выводит полное название класса с указанием пространства имен, в котором определен этот класс. И мы можем переопределить данный метод. Посмотрим на примере:

Person person = new Person { Name = "Tom" };
Console.WriteLine(person.ToString()); // выведет название класса Person

Clock clock = new Clock { Hours = 15, Minutes = 34, Seconds = 53 };
Console.WriteLine(clock.ToString()); // выведет 15:34:53

class Clock
{
    public int Hours { get; set; }
    public int Minutes { get; set; }
    public int Seconds { get; set; }
    public override string ToString()
    {
        return $"{Hours}:{Minutes}:{Seconds}";
    }
}
class Person
{
    public string Name { get; set; } = "";
}

Для переопределения метода ToString() в классе Clock, который представляет часы, используется ключевое слово override (как и при обычном переопределении виртуальных или абстрактных методов). В данном случае метод ToString() выводит в строке значения свойств Hours, Minutes, Seconds.

Класс Person не переопределяет метод ToString, поэтому для этого класса срабатывает стандартная реализация этого метода, которая выводит просто название класса.

Кстати в данном случае мы могли задействовать обе реализации:

Person tom = new Person { Name = "Tom" };
Console.WriteLine(tom.ToString()); // Tom

Person undefined = new Person();
Console.WriteLine(undefined.ToString()); // Person

class Person
{
    public string Name { get; set; } = "";

    public override string? ToString()
    {
        if (string.IsNullOrEmpty(Name))
            return base.ToString();
        return Name;
    }
}

То есть если имя - свойство Name не имеет значения, оно представляет пустую строку, то возвращается базовая реализация - название класса. Стоит отметить, что базовая реализация возвращает не просто строку, а объект string? - то есть это может быть строка string, либо значение null, которое указывает на отсутствие значения. И в реальности в качестве возвращаемого типа для метода мы можем использовать как string, так и string?

Если же имя у объекта Person установлено, то возвращается значение свойства Name. Для проверки строки на наличие значения применяется метод String.IsNullOrEmpty().

Стоит отметить, что различные технологии на платформе .NET активно используют метод ToString для разных целей. В частности, тот же метод Console.WriteLine() по умолчанию выводит именно строковое представление объекта. Поэтому, если нам надо вывести строковое представление объекта на консоль, то при передаче объекта в метод Console.WriteLine необязательно использовать метод ToString() - он вызывается неявно:

Person person = new Person { Name = "Tom" };
Console.WriteLine(person);	// Tom

Clock clock = new Clock { Hours = 15, Minutes = 34, Seconds = 53 };
Console.WriteLine(clock); // выведет 15:34:53

Метод GetHashCode

Метод GetHashCode позволяет возвратить некоторое числовое значение, которое будет соответствовать данному объекту или его хэш-код. По данному числу, например, можно сравнивать объекты. Можно определять самые разные алгоритмы генерации подобного числа или взять реализацию базового типа:

class Person
{
    public string Name { get; set; } = "";

    public override int GetHashCode()
    {
		return Name.GetHashCode();
    }
}

В данном случае метод GetHashCode возвращает хеш-код для значения свойства Name. То есть два объекта Person, которые имеют одно и то же имя, будут возвращать один и тот же хеш-код. Однако в реальности алгоритм может быть самым различным.

Получение типа объекта и метод GetType

Метод GetType позволяет получить тип данного объекта:

Person person = new Person { Name = "Tom" };
Console.WriteLine(person.GetType());	// Person

Этот метод возвращает объект Type, то есть тип объекта.

С помощью ключевого слова typeof мы получаем тип класса и сравниваем его с типом объекта. И если этот объект представляет тип Person, то выполняем определенные действия.

object person = new Person { Name = "Tom" };
if (person.GetType() == typeof(Person))
	Console.WriteLine("Это реально класс Person");

Причем поскольку класс Object является базовым типом для всех классов, то мы можем переменной типа object присвоить объект любого типа. Однако для этой переменной метод GetType все равно вернет тот тип, на объект которого ссылается переменная. То есть в данном случае объект типа Person.

Стоит отметить, что проверку типа в примере выше можно сократить с помощью оператора is:

object person = new Person { Name = "Tom" };
if (person is Person)
    Console.WriteLine("Это реально класс Person");

В отличие от методов ToString, Equals, GetHashCode метод GetType() не переопределяется.

Метод Equals

Метод Equals позволяет сравнить два объекта на равенство. В качестве параметра он принимает объект для сравнения в виде типа object и возврашает true, если оба объекта равны:

public override bool Equals(object? obj) {......}

Например, реализуем данный метод в классе Person:

class Person
{
	public string Name { get; set; } = "";
    public override bool Equals(object? obj)
    {
        // если параметр метода представляет тип Person
        // то возвращаем true, если имена совпадают
        if (obj is Person person) return Name == person.Name;
        return false;
    }
    // вместе с методом Equals следует реализовать метод GetHashCode
    public override int GetHashCode() => Name.GetHashCode();
}

Метод Equals принимает в качестве параметра объект любого типа, который мы затем приводим к текущему классу - классу Person.

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

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

Стоит отметить, что вместе с методом Equals следует реализовать метод GetHashCode.

Применение метода:

var person1 = new Person { Name = "Tom" };
var person2 = new Person { Name = "Bob" };
var person3 = new Person { Name = "Tom" };

bool person1EqualsPerson2 = person1.Equals(person2);   // false
bool person1EqualsPerson3 = person1.Equals(person3);   // true

Console.WriteLine(person1EqualsPerson2);    // false
Console.WriteLine(person1EqualsPerson3);    // true

И если следует сравнивать два сложных объекта, как в данном случае, то лучше использовать метод Equals, а не стандартную операцию ==.

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850