Язык программирования C#9 и платформа .NET5
Часть 148 из 642 Информация о книге
Чтобы проиллюстрировать стандартное поведение, обеспечиваемое базовым классом
, создайте новый проект консольного приложения C# по имениObject.ObjectOverridesДобавьте в проект новый файл класса С#, содержащий следующее пустое определение типа
:Person// Не забывайте, что класс Person расширяет Object.class Person {}Теперь обновите операторы верхнего уровня для взаимодействия с унаследованными членами
:System.ObjectConsole.WriteLine("***** Fun with System.Object *****\n");Person p1 = new Person();// Использовать унаследованные члены System.Object.Console.WriteLine("ToString: {0}", p1.ToString());Console.WriteLine("Hash code: {0}", p1.GetHashCode());Console.WriteLine("Type: {0}", p1.GetType());// Создать другие ссылки на pi.Person p2 = p1;object o = p2;// Указывают ли ссылки на один и тот же объект в памяти?if (o.Equals(p1) && p2.Equals(o)){Console.WriteLine("Same instance!");}Console.ReadLine();}Вот вывод, получаемый в результате выполнения этого кода:
***** Fun with System.Object *****ToString: ObjectOverrides.PersonHash code: 58225482Type: ObjectOverrides.PersonSame instance!Обратите внимание на то, что стандартная реализация
возвращает полностью заданное имя текущего типа (ToString()). Как будет показано в главе 15, где исследуется построение специальных пространств имен, каждый проект C# определяет "корневое пространство имен", название которого совпадает с именем проекта. Здесь мы создали проект по имениObjectOverrides.Person, поэтому типObjectOverridesи классPersonпомещены внутрь пространства именProgram.ObjectOverridesСтандартное поведение метода
заключается в проверке, указывают ли две переменные на один и тот же объект в памяти. В коде мы создаем новую переменнуюEquals()по имениPerson. В этот момент новый объектpiпомещается в управляемую кучу. ПеременнаяPersonтакже относится к типур2. Тем не менее, вместо создания нового экземпляра переменнойPersonприсваивается ссылкар2. Таким образом, переменныеpiиpiуказывают на один и тот же объект в памяти, как и переменнаяр2(типао). Учитывая, чтоobject,piир2указывают на одно и то же местоположение в памяти, проверка эквивалентности дает положительный результат.оХотя готовое поведение
в ряде случаев может удовлетворять всем потребностям, довольно часто в специальных типах часть этих унаследованных методов переопределяется. В целях иллюстрации модифицируем классSystem.Object, добавив свойства, которые представляют имя, фамилию и возраст лица; все они могут быть установлены с помощью специального конструктора:Person// Не забывайте, что класс Person расширяет Object.class Person{public string FirstName { get; set; } = "";public string LastName { get; set; } = "";public int Age { get; set; }public Person(string fName, string lName, int personAge){FirstName = fName;LastName = lName;Age = personAge;}public Person(){}}Переопределение метода System.Object.ToString()
Многие создаваемые классы (и структуры) могут извлечь преимущества от переопределения метода
для возвращения строки с текстовым представлением текущего состояния экземпляра типа. Помимо прочего это полезно при отладке. То, как вы решите конструировать результирующую строку — дело личных предпочтений; однако рекомендуемый подход предусматривает отделение пар "имя-значение" друг от друга двоеточиями и помещение всей строки в квадратные скобки (такому принципу следуют многие типы из библиотек базовых классов .NET Core). Взгляните на следующую переопределенную версиюToString()для классаToString():Personpublic override string ToString()=> $"[First Name: {FirstName}; Last Name: {LastName};Age:{Age}]";Приведенная реализация метода
довольно прямолинейна, потому что классToString()содержит всего три порции данных состояния. Тем не менее, всегда помните о том, что правильное переопределениеPersonдолжно также учитывать любые данные, определенные выше в цепочке наследования.ToString()
