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

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 115 116 117 118 119 120 121 122 123 ... 407
// Этот вспомогательный класс используется для сортировки

  // массива объектов Car по дружественному имени.

  public class PetNameComparer : IComparer

  {

    // Проверить дружественное имя каждого объекта.

    int IComparer.Compare(object o1, object o2)

    {

      if (o1 is Car t1 && o2 is Car t2)

      {

        return string.Compare(t1.PetName, t2.PetName,

          StringComparison.OrdinalIgnoreCase);

      }

      else

      {

        throw new ArgumentException("Parameter is not a Car!");

                            // Параметр не является объектом типа Car!

      }

    }

  }

}

Вспомогательный класс PetNameComparer может быть задействован в коде. Класс System.Array содержит несколько перегруженных версий метода Sort(), одна из которых принимает объект, реализующий интерфейс IComparer:

...

// Теперь сортировать по дружественному имени.

Array.Sort(myAutos, new PetNameComparer());

// Вывести отсортированный массив.

Console.WriteLine("Ordering by pet name:");

foreach(Car c in myAutos)

{

  Console.WriteLine("{0} {1}", c.CarID, c.PetName);

}

...

Специальные свойства и специальные типы сортировки

Важно отметить, что вы можете применять специальное статическое свойство, оказывая пользователю объекта помощь с сортировкой типов Car по специфичному элементу данных. Предположим, что в класс Car добавлено статическое свойство только для чтения по имени SortByPetName, которое возвращает экземпляр класса, реализующего интерфейс IComparer (в этом случае PetNameComparer; не забудьте импортировать пространство имен System.Collections):

// Теперь мы поддерживаем специальное свойство для возвращения

// корректного экземпляра, реализующего интерфейс IComparer.

public class Car : IComparable

{

...

  // Свойство, возвращающее PetNameComparer.

  public static IComparer SortByPetName

    => (IComparer)new PetNameComparer();}

Теперь в коде массив можно сортировать по дружественному имени, используя жестко ассоциированное свойство, а не автономный класс PetNameComparer:

// Сортировка по дружественному имени становится немного яснее.

Array.Sort(myAutos, Car.SortByPetName);

К настоящему моменту вы должны не только понимать способы определения и реализации собственных интерфейсов, но также оценить их полезность. Конечно, интерфейсы встречаются внутри каждого важного пространства имен .NET Core, а в оставшихся главах книги вы продолжите работать с разнообразными стандартными интерфейсами.

Резюме

Интерфейс может быть определен как именованная коллекция абстрактных членов. Интерфейс общепринято расценивать как поведение, которое может поддерживаться заданным типом. Когда два или больше число типов реализуют один и тот же интерфейс, каждый из них может трактоваться одинаковым образом (полиморфизм на основе интерфейсов), даже если типы определены в разных иерархиях.

Для определения новых интерфейсов в языке C# предусмотрено ключевое слово interface. Как было показано в главе, тип может поддерживать столько интерфейсов, сколько необходимо, и интерфейсы указываются в виде списка с разделителями-запятыми. Более того, разрешено создавать интерфейсы, которые являются производными от множества базовых интерфейсов.

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

Глава 9

Время существования объектов

К настоящему моменту вы уже умеете создавать специальные типы классов в С#. Теперь вы узнаете, каким образом исполняющая среда управляет размещенными экземплярами классов (т.е. объектами) посредством сборки мусора. Программистам на C# никогда не приходится непосредственно удалять управляемый объект из памяти (вспомните, что в языке C# даже нет ключевого слова наподобие delete). Взамен объекты .NET Core размещаются в области памяти, которая называется управляемой кучей, где они автоматически уничтожаются сборщиком мусора "в какой-то момент в будущем".

После изложения основных деталей, касающихся процесса сборки мусора, будет показано, каким образом программно взаимодействовать со сборщиком мусора, используя класс System.GC (что в большинстве проектов обычно не требуется). Мы рассмотрим, как с применением виртуального метода System.Object.Finalize() и интерфейса IDisposable строить классы, которые своевременно и предсказуемо освобождают внутренние неуправляемые ресурсы.

Кроме того, будут описаны некоторые функциональные возможности сборщика мусора, появившиеся в версии .NET 4.0, включая фоновую сборку мусора и ленивое (отложенное) создание объектов с использованием обобщенного класса System.Lazy<>. После освоения материалов данной главы вы должны хорошо понимать, каким образом исполняющая среда управляет объектами .NET Core.

Классы, объекты и ссылки

Прежде чем приступить к исследованию основных тем главы, важно дополнительно прояснить отличие между классами, объектами и ссылочными переменными. Вспомните, что класс — всего лишь модель, которая описывает то, как экземпляр такого типа будет выглядеть и вести себя в памяти. Разумеется, классы определяются внутри файлов кода (которым по соглашению назначается расширение *.cs). Взгляните на следующий простой класс Car, определенный в новом проекте консольного приложения C# по имени SimpleGC:

namespace SimpleGC

{

  // Car.cs

  public class Car

  {

    public int CurrentSpeed {get; set;}

    public string PetName {get; set;}

    public Car(){}

    public Car(string name, int speed)

    {

      PetName = name;

      CurrentSpeed = speed;

    }

    public override string ToString()

      => $"{PetName} is going {CurrentSpeed} MPH";

    }

  }

}

После того как класс определен, в памяти можно размещать любое количество его объектов, применяя ключевое слово new языка С#. Однако следует иметь в виду, что ключевое слово new возвращает ссылку на объект в куче, а не действительный объект. Если ссылочная переменная объявляется как локальная переменная в области действия метода, то она сохраняется в стеке для дальнейшего использования внутри приложения. Для доступа к членам объекта в отношении сохраненной ссылки необходимо применять операцию точки С#:

using System;

using SimpleGC;

Console.WriteLine("***** GC Basics *****");

// Создать новый объект Car в управляемой куче.

// Возвращается ссылка на этот объект (refToMyCar).

Car refToMyCar = new Car("Zippy", 50);

// Операция точки (.) используется для обращения к членам

// объекта с применением ссылочной переменной.

Console.WriteLine(refToMyCar.ToString());

Console.ReadLine();

На заметку! Вспомните из главы 4, что структуры являются типами значений, которые всегда размещаются прямо в

1 ... 115 116 117 118 119 120 121 122 123 ... 407
На этой странице вы можете бесплатно читать книгу Язык программирования C#9 и платформа .NET5 - Эндрю Троелсен бесплатно.

Оставить комментарий