Курс лекций для студентов специальности i-31 03 04 Информатика всех форм обучения Минск 2010



страница5/29
Дата09.08.2019
Размер0.64 Mb.
#126834
ТипКурс лекций
1   2   3   4   5   6   7   8   9   ...   29

Сравнение для выяснения порядка


Стандартным способом сравнения для выяснения порядка является реализация типом интерфейсов IComparable и IComparable:

public interface IComparable

{

int CompareTo(object other);



}
public interface IComparable

{

int CompareTo(T other);



}

Оба интерфейса представляют одинаковый функционал. Универсальный интерфейс IComparable избавляет от необходимости упаковки при работе с типами значений. Метод x.CompareTo(y) должен возвращать положительное число, если x «больше» y, отрицательное число, если x «меньше» y, и ноль, если x и y равны.

Базовые типы реализуют обе версии интерфейса IComparable. В типе string метод CompareTo() выполняет чувствительное к регистру сравнение строк с учетом региональных стандартов. В некоторых базовых типах дополнительно определён статический метод сравнения Compare(). Например, тип string имеет перегруженные версии Compare(), которые принимают или параметр StringComparison, или булевский флаг (игнорирование регистра) и объект CultureInfo:

// порядковое сравнение

int i = string.Compare("Strasse", "Straße", StringComparison.Ordinal);

// создадим объект с информацией о немецкой культуре

CultureInfo german = CultureInfo.GetCultureInfo("de-DE");

// значение i равно 0 – в немецком языке такие слова равны

i = string.Compare("Strasse", "Straße", false, german);

Кроме реализации IComparable и IComparable тип может перегружать операции < и >. Перегрузка операций сравнения обычно выполняется, если результат операции не зависит от контекста выполнения1.

bool after2012 = DateTime.Now > new DateTime(2012, 1, 1);

Как и в случае проверки на равенство, сравнение для выяснения порядка можно выполнить при помощи подключаемых интерфейсов. Для порядкового сравнения предназначены интерфейсы IComparer и IComparer (пространства имён System.Collections.Generic и System.Collections).

public interface IComparer

{

int Compare(object x, object y);



}
public interface IComparer

{

int Compare(T x, T y);



}

Существует абстрактный класс System.Collections.Generic.Comparer, облегчающий реализацию интерфейсов IComparer и IComparer:

public class Wish

{

public string Name { get; set; }



public int Priority { get; set; }

}
public class PriorityComparer : Comparer

{

public override int Compare(Wish x, Wish y)



{

if (Equals(x, y)) return 0;

return x.Priority.CompareTo(y.Priority);

}

}



Статическое свойство Comparer.Default возвращает экземпляр Comparer для типа T. Этот экземпляр использует метод CompareTo(T) либо метод CompareTo(object) в зависимости от того, реализует ли T интерфейс IComparable.

Абстрактный класс System.StringComparer предназначен для сравнения строк с учетом языка и регистра. Этот класс реализует интерфейсы IComparer, IEqualityComparer, IComparer и IEqualityComparer. Некоторые неабстрактные наследники StringComparer доступны через его статические свойства. Например, свойство StringComparer.CurrentCulture возвращает объект, реализующий сравнение строк с учетом текущих региональных стандартов.


2.6. Жизненный цикл объектов


Все типы платформы .NET делятся на ссылочные типы и типы значений. Переменные типов значений создаются в стеке, и их время жизни ограничено тем блоком кода, в котором они объявляются. Например, если переменная типа значения объявлена в некотором методе, то после выхода из метода память в стеке, занимаемая переменной, автоматически освободится.

Переменные ссылочного типа (объекты) располагаются в динамической памяти – «управляемой куче» (managed heap). Размещение объектов в «куче» происходит последовательно. Для этого CLR поддерживает указатель на свободное место в куче, перемещая его на соответствующее количество байт после выделения памяти очередному объекту.


Алгоритм «сборки мусора»


Если при работе программы превышен некий порог расхода памяти, CLR запускает процесс, называемый сборка мусора1. На первом этапе сборки мусора строится граф используемых объектов. Отправными точками в построении графа являются корневые объекты. Это объекты следующих категорий:

  • локальная переменная или параметр выполняемого метода (а также всех методов в стеке вызова);

  • статическое поле;

  • объект в очереди завершения (этот термин будет разъяснён позже).

При помощи графа используемых объектов выясняется реально занимаемая этими объектами память. Затем происходит дефрагментация «кучи»  используемые объекты перераспределяются так, чтобы занимаемая ими память составляла единый блок в начале «кучи». Ключевой особенностью сборки мусора является то, что она осуществляется автоматически и независимо от потоков выполнения приложения2.

При размещении и удалении объектов CLR использует ряд оптимизаций. Во-первых, объекты размером более 85 Кб размещаются в отдельной управляемой куче. При сборке мусора данная куча не дефрагментируется, так как копирование больших блоков памяти снижает производительность. Во-вторых, управляемая куча для малых объектов выделяет три поколения объектов – Gen0, Gen1 и Gen2. Вначале все объекты в куче относятся к Gen0. После первой сборки мусора те объекты, которые не были удалены, переходят в поколение Gen1, а новые объекты будут принадлежать Gen0. Вторая сборка мусора порождает поколение Gen2. Процесс сборки мусора работает с объектами старших поколений, только если освобождение памяти в младших поколениях дало неудовлетворительный результат.


Финализаторы и интерфейс IDisposable


Обсудим автоматическую сборку мусора с точки зрения программиста, разрабатывающего некий класс. С одной стороны, такой подход имеет свои преимущества. В частности, практически исключаются случайные утечки памяти, которые могут вызвать «забытые» объекты. С другой стороны, объект может захватить некоторые особо ценные ресурсы (например, подключения к базе данных), которые требуется освободить сразу после того, как объект перестаёт использоваться. В такой ситуации выходом является написание особого метода, который содержит код освобождения ресурсов.

Но как гарантировать освобождение ресурсов, даже если ссылка на объект была случайно утеряна? Класс System.Object содержит виртуальный метод Finalize(). Если объект пользовательского класса при работе захватывает ресурсы, класс может переопределить метод Finalize() для их освобождения. Объекты таких классов при сборке мусора обрабатываются особо. Когда сборщик мусора распознаёт, что уничтожаемый объект имеет собственную реализацию метода Finalize(), он помещает такой объект в специальную очередь завершения. Затем в отдельном программном потоке у объектов из очереди завершения происходит вызов метода Finalize() и фактическое уничтожение.

Язык C# не позволяет явно переопределить в пользовательском классе метод Finalize(). Вместо переопределения Finalize() в классе описывается специальный финализатор. Имя финализатора имеет вид ~<имя класса>, он не имеет параметров и модификаторов доступа (считается, что модификатор доступа финализатора  protected, а значит, его нельзя явно вызвать у объекта). При наследовании в финализатор класса-наследника автоматически подставляется вызов финализатора класса-предка.

Рассмотрим пример класса с финализатором:

public class ClassWithFinalizer

{

public void DoSomething()



{

Console.WriteLine("I'm working...");

}
~ClassWithFinalizer()

{

Console.WriteLine("Bye!");



}

}

Приведем пример программы, использующей этот класс:



public class MainClass

{

private static void Main()



{

var A = new ClassWithFinalizer();

A.DoSomething();

// cборка мусора запуститься перед завершением приложения

}

}

Данная программа выводит следующие строки:



I'm working...

Bye!


Проблема с использованием финализатора заключается в недетерминированности его вызова. Программист может описать в классе некий метод, который следует вызывать «вручную», когда объект больше не нужен. Для унификации данного решения платформа .NET предлагает интерфейс IDisposable, содержащий единственный метод Dispose(), куда помещается завершающий код работы с объектом.

Правильный шаблон совместного использования финализатора и интерфейса IDisposable демонстрирует следующий класс:

public class DisposePattern : IDisposable

{

public void Dispose() // реализация IDisposable



{

Dispose(true);

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

GC.SuppressFinalize(this);

}

~DisposePattern() // реализация финализатора



{

Dispose(false);

}

protected virtual void Dispose(bool disposing)



{

if (disposing)

{

// вызов из Dispose() – полное контролируемое удаление



}

// этот блок выполняется только для вызова из финализатора

}

}

Язык C# имеет специальный оператор using, который гарантирует вызов метода Dispose() для объектов, используемых в своем блоке. Синтаксис оператора using следующий:



using (<имя объекта или объявление и создание объектов>) <блок кода>

Продемонстрируем использование оператора using:

using (var A = new DisposePattern())

{

A.DoSomething();



// компилятор поместит сюда вызов A.Dispose()

}

Сборщик мусора представлен статическим классом System.GC, который обладает несколькими полезными методами (это неполный список):



  • Collect()  вызывает принудительную сборку мусора в программе.

  • GetGeneration() – возвращает поколение для указанного объекта;

  • SuppressFinalize()  подавляет вызов финализатора для указанного объекта;

  • WaitForPendingFinalizers()  приостанавливает текущий поток выполнения до тех пор, пока не будут выполнены все финализаторы освобождаемых объектов.


Каталог: images
images -> В списке студентов (или магистрантов)
images -> Н. И. Сулейманов Комплект контрольно-оценочных средств для оценки результатов освоения профессионального модуля разработан на основе Федерального государственного образовательного стандарта среднего профессионального
images -> По направлению подготовки
images -> Добавить гаджеты. Добавление гаджетов
images -> Техническое задание № apnip/C. 2/CS/Ind/01 Международный консультант по улучшенной производительности орошаемого земледелия
images -> Комплект контрольно-оценочных средств по профессиональному модулю пм. 01 Техническое обслуживание и ремонт автотранспорта


Поделитесь с Вашими друзьями:
1   2   3   4   5   6   7   8   9   ...   29




База данных защищена авторским правом ©vossta.ru 2022
обратиться к администрации

    Главная страница