Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Заочники_АСОИ / Лекции / 01 Классы / Объекты и типы.docx
Скачиваний:
20
Добавлен:
29.02.2016
Размер:
97.14 Кб
Скачать

Автоматически реализуемые свойства

Если наличие какой-либо логики в методах set и get свойства не предполагается, мож­но использовать автоматически реализуемые свойства. Такие свойства создают поддержи­вающие их переменные-члены автоматически. Код ранее приведенного примера с Age вы­глядел бы следующим образом:

public int Age (get; set;}

В объявлении private int age; нет необходимости — компилятор создаст его авто­матически.

При использовании автоматически реализуемых свойств проверка достоверности свой­ства не может быть выполнена в его методе set. Поэтому в предыдущем примере мы бы не смогли проверить корректность установки возраста. Также должны присутствовать оба метода доступа. То есть, попытка сделать свойство доступным только для чтения вызовет ошибку:

public int Age (get;)

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

public int Age (get; private set; }

Замечание о встраивании

Некоторые разработчики могут быть обеспокоены тем, что в предыдущих разделах де­монстрируется множество ситуаций, когда стандартная практика кодирования С# порож­дает множество очень маленьких функций  например, для доступа к полю через свойство вместо непосредственного обращения к нему. Не повлияет ли это на производительность из-за накладных расходов, связанных с дополнительными вызовами функций? Ответ со­стоит в том, что не нужно беспокоиться о потере производительности по причине такой методологии программирования на С#. Вспомните, что код С# транслируется в IL, а затем JIT компилирует его во время выполнения в родной исполняемый код. JIT-компилятор спроектирован так, что генерирует высоко оптимизированный код и без колебаний ис­пользует встроенный (inline) код там, где это необходимо (т.е. заменяет вызовы функций встроенным кодом). Метод или свойство, чья реализация просто вызывает другой метод или возвращает поле, почти наверняка будет преобразован во встроенный код. Однако следует отметить, что решение относительно встраивания принимает исключительно CLR. У вас нет никакой возможности управлять тем, какие методы будут встроенными  например, с помощью какого-то ключевого слова вроде применяемого в С++ inline.

Индексаторы

Как вам должно быть уже известно, индексирование массива осуществляется с помощью оператора []. Для создаваемых классов можно определить оператор [], но с этой целью вместо операторного метода создается индексатор, который позволяет индексировать объект, по­добно массиву. Индексаторы применяются, главным об­разом, в качестве средства, поддерживающего создание специализированных массивов, на которые накладывается одно или несколько ограничений. Тем не менее индексато­ры могут служить практически любым целям, для которых выгодным оказывается такой же синтаксис, как и у масси­вов. Индексаторы могут быть одно- или многомерными.

Рассмотрим сначала одномерные индексаторы.

Создание одномерных индексаторов

Ниже приведена общая форма одномерного индексатора:

Тип_элемента this[int индекс]

{

// Аксессор для получения данных

get

{

// Возврат значения, которое определяет индекс.

}

// Аксессор для установки данных

set

{

// Установка значения, которое определяет индекс.

}

}

где тип_элемента обозначает конкретный тип элемента индексатора. Следовательно, у каждого элемента, доступного с помощью индексатора, должен быть определенный тип_элемента. Этот тип соответствует типу элемента массива. Параметр индекс по­лучает конкретный индекс элемента, к которому осуществляется доступ. Формально этот параметр совсем не обязательно должен иметь тип int, но поскольку индексато­ры, как правило, применяются для индексирования массивов, то чаще всего использу­ется целочисленный тип данного параметра.

В теле индексатора определены два аксессора (т.е. средства доступа к данным): get и set. Аксессор подобен методу, за исключением того, что в нем не объявляется тип возвращаемого значения или параметры. Аксессоры вызываются автоматически при использовании индексатора, и оба получают: индекс в качестве параметра. Так, если индексатор указывается в левой части оператора присваивания, то вызывается аксессор set и устанавливается элемент, на который указывает параметр индекс. В противном случае вызывается аксессор get и возвращается значение, соответствующее параметру индекс. Кроме того, аксессор set получает неявный параметр value, содержащий значение, присваиваемое по указанному индексу.

Преимущество индексатора заключается, в частности, в том, что он позволяет пол­ностью управлять доступом к массиву, избегая нежелательного доступа. В качестве примера рассмотрим программу, в которой создается класс FailSoftArray, реали­зующий массив для выявления ошибок нарушения границ массива, а следовательно, для предотвращения исключительных ситуаций, возникающих во время выполнения в связи с индексированием массива за его границами. Для этого массив инкапсулиру­ется в качестве закрытого члена класса, а доступ к нему осуществляется только с помо­щью индексатора. При таком подходе исключается любая попытка получить доступ к массиву за его границами, причем эта попытка пресекается без катастрофических последствий для программы. А поскольку в классе FailSoftArray используется ин­дексатор, то к массиву можно обращаться с помощью обычной формы записи.

Соседние файлы в папке 01 Классы