Выбери любимый жанр

Язык программирования C#9 и платформа .NET5 - Троелсен Эндрю - Страница 180


Изменить размер шрифта:

180

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

Clone()
объект
Point
действительно копирует свои внутренние переменные-члены ссылочного типа (обратите внимание, что дружественные имена у
рЗ
и
р4
теперь уникальны):

***** Fun with Object Cloning *****

Cloned p3 and stored new Point in p4

Before modification:

p3: X = 100; Y = 100; Name = Jane;

ID = 51f64f25-4b0e-47ac-ba35-37d263496406

p4: X = 100; Y = 100; Name = Jane;

ID = 0d3776b3-b159-490d-b022-7f3f60788e8a

Changed p4.desc.petName  and p4.X

After modification:

p3: X = 100; Y = 100; Name = Jane;

ID = 51f64f25-4b0e-47ac-ba35-37d263496406

p4: X = 9; Y = 100; Name = My new Point;

ID = 0d3776b3-b159-490d-b022-7f3f60788e8a

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

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

Интерфейс IComparable

Интерфейс

System.IComparable
описывает поведение, которое позволяет сортировать объекты на основе указанного ключа. Вот его формальное определение:

// Данный интерфейс позволяет объекту указывать

// его отношение с другими подобными объектами

public interface IComparable

{

  int CompareTo(object o);

}

На заметку! Обобщенная версия этого интерфейса (

IСоmраrаble<Т>
) предлагает более безопасный в отношении типов способ обработки операций сравнения объектов. Обобщения исследуются в главе 10.

Создайте новый проект консольного приложения по имени

ComparableCar
, скопируйте классы
Car
и
Radio
из проекта
SimpleException
, рассмотренного в главе 7, и поменяйте пространство имен в каждом файле класса на
ComparableCar
. Обновите класс
Car
, добавив новое свойство для представления уникального идентификатора каждого автомобиля и модифицированный конструктор:

using System;

using System.Collections;

namespace ComparableCar

{

  public class Car

  {

    ...

    public int CarID {get; set;}

    public Car(string name, int currSp, int id)

    {

      CurrentSpeed = currSp;

      PetName = name;

      CarID = id;

    }

    ...

  }

}

Теперь предположим, что имеется следующий массив объектов

Car
:

using System;

using ComparableCar;

Console.WriteLine("***** Fun with Object Sorting *****\n");

// Создать массив объектов Car.

Car[] myAutos = new Car[5];

myAutos[0] = new Car("Rusty", 80, 1);

myAutos[1] = new Car("Mary", 40, 234);

myAutos[2] = new Car("Viper", 40, 34);

myAutos[3] = new Car("Mel", 40, 4);

myAutos[4] = new Car("Chucky", 40, 5);

Console.ReadLine();

В классе

System.Array
определен статический метод по имени
Sort()
. Его вызов для массива внутренних типов (
int
,
short
,
string
и т.д.) приводит к сортировке элементов массива в числовом или алфавитном порядке, т.к. внутренние типы данных реализуют интерфейс
IComparable
. Но что произойдет, если передать методу
Sort()
массив объектов
Car
?

// Сортируются ли объекты Car? Пока еще нет!

Array.Sort(myAutos);

Запустив тестовый код, вы получите исключение времени выполнения, потому что класс

Car
не поддерживает необходимый интерфейс. При построении специальных типов вы можете реализовать интерфейс
IComparable
, чтобы позволить массивам, содержащим элементы этих типов, подвергаться сортировке. Когда вы реализуете детали
СоmраrеТо()
, то должны самостоятельно принять решение о том, что должно браться за основу в операции упорядочивания. Для типа
Car
вполне логичным кандидатом может служить внутреннее свойство
CarID
:

// Итерация по объектам Car может быть упорядочена на основе CarID.

public class Car : IComparable

{

180
Перейти на страницу:
Мир литературы