Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции ЛИПО .doc
Скачиваний:
3
Добавлен:
17.08.2019
Размер:
420.86 Кб
Скачать

Класс Object

Классы .NET изначально унаследованы от System.Object. Фактически, если не указывать базовый класс при определении нового клас­са, компилятор автоматически предполагает, что он наследуется от Object. Все классы, которые мы виде­ли до сих пор, на самом деле унаследованы от System.Object. (Как упоминалось выше, для структур это наследование непрямое. Структуры всегда наследуются от System. ValueType, который, в свою очередь, унаследован от System.Object.)

Практическое значение этого в том, что помимо методов и свойств, которые вы определяете, вы также получаете доступ к множеству общедоступных и защищенных методов-членов, которые определены в классе Object. Эти методы присутствуют во всех классах, которые вы определяете.

Структуры

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

Рассмотрим пример:

class Dimensions

public double Length;

public double Width;

Этот код определяет класс Dimensions, который просто сохраняет длину и ширину некоторого элемента. Все, что нужно — два числа, которые удобнее хранить вместе, чем по отдельности. Как упоминалось ранее единственное, что нужно изменить в чтобы сделать этот тип структурой вместо класса — это просто заменить ключевое class на struct:

struct Dimensions

public double Length;

public double Width;

Определение функций для структур выглядит точно так же, как определение для классов. Следующий код демонстрирует структуру с конструктором и свойством:

struct Dim

{

public int a;

public int b;

Dim(int new_a, int new_b)

{

a = new_a;

b = new_b;

}

public int area

{

get

{

return a*b;

}

}

}

Во многих отношениях структуры С# можно воспринимать как упрощенные классы, В основном они такие же, как классы, но предназначены в большей степени для тех случаев когда необходимо просто группировать некоторые данные в одном месте.

Отличия структур от классов заключаются в следующем:

  • Структуры — это типы значений, а не ссылочные типы. Это значит, что он либо сохраняются в стеке, либо являются встроенными (последнее — если они являются частью другого объекта, хранимого в куче), и имеют те же ограниче­ния времени жизни, что и простые типы данных.

  • Структуры не поддерживают наследование.

  • Существует некоторое отличие в работе конструкторов структур. В частности компилятор всегда генерирует конструктор по умолчанию без параметров, ко­торый переопределить невозможно.

Поскольку структуры на самом деле предназначены для группирования данных, в большинстве случаев все их поля объявляются общедоступными. Строго говоря, это противоречит рекомендациям по написанию кода .NET. Согласно Microsoft, поля (кроме константных) всегда должны быть приватными и помещенными в оболочки общедоступных свойств. Однако что касается простых структур, многие разработчики считают применение общедоступных полей допустимой практикой программирования.

Стоит отметить, что реализация структур C++ и С# серьезно отличается, от реализации классов. В этом смысле ситуация совсем не похожа на C++, где структу­ры и классы - практически одно и тоже.

Допишем программу:

class Program

{

static void Main(string[] args)

{

Dim dim_1;

dim_1.b = 5;

dim_1.a = 6;

Console.WriteLine(dim_1.area);

Console.ReadLine();

}

}

Хотя структуры относятся к типам значений, очень часто их можно трактовать так же, как классы. Например, имея определение класса Dim из предыдущего примера, можно написать:

Dim dim_1 = new Dim();

dim_1.b = 5;

dim_1.a = 6;

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

Dim dim_1;

dim_1.b = 5;

dim_1.a = 6;

Если бы dim_1 был классом, это привело бы к ошибке компиляции, потом) что point содержал бы неинициализированную ссылку — то есть адрес, никуда не указывающий, а потому было бы невозможно присваивать значения его полям. Для струк­тур же объявление переменной на самом деле выделяет пространство в стеке для полной структуры, поэтому она тут же готова к присвоению значений полям.

Структуры следуют тем же правилам, что и все другие типы данных: все должно быть инициализировано перед использованием. Структура рассматривается как полностью инициализированная, когда для ее создания была вызвана операция new, или же когда всем ее полям индивидуально были присвоены значения. И естественно структура, определенная как поле класса, инициализируется автоматическим обнуле­нием при инициализации ее включающего объекта.

Тот факт, что структуры — это типы значений, оказывает влияние на производительность. В зависимости от того, как использовать структуры, это может быть и плохо и хорошо. Положительным является то, что выделение памяти для структур происходит очень быстро, потому что они встроены или размещаются в стеке. То же самое касается удаления структур при выходе из контекста. С другой стороны, всякий раз когда вы передаете структуру в виде параметра, или присваиваете одну структуру другой (как в А=В, когда А и В — структуры), то происходит копирование всего содержимого структуры, в то время как в случае с классами копируется только ссылка. Это приводит к потерям производительности, которые зависят от размера структуры — это подчеркивает тот факт, что структуры на самом деле предназначены для хранения небольших порций данных. Отметим, однако, что когда структура передается методу в виде параметра, этих потерь производительности можно избежать, применяя ref - параметры — при этом передается только адрес в памяти, где находится структура. Это так же быстро, как и передача объекта класса. С другой стороны, если так делать, то необходимо помнить, что вызываемый метод может в принципе изменить значение переданной структуры.