Ограничения, присущие свойствам 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Ограничения, присущие свойствам

10.2.3 Ограничения, присущие свойствам

Свойствам присущ ряд существенных ограничений. Во-первых, свойство не опреде­ляет место для хранения данных, и поэтому не может быть передано методу в качестве параметра ref или out. Во-вторых, свойство не подлежит перегрузке. Наличие двух разных свойств с доступом к одной и той же переменной допускается, но это, скорее, исключение, чем правило. И наконец, свойство не должно изменять состояние базо­вой переменной при вызове аксессора get. И хотя это ограничительное правило не соблюдается компилятором, его нарушение считается семантической ошибкой. Дей­ствие аксессора get не должно носить характер вмешательства в функционирование переменной.

10.3 Применение модификаторов доступа в аксессорах

По умолчанию доступность аксессоров set и get оказывается такой же, как и у индексатора и свойства, частью которых они являются. Так, если свойство объявляется как public, то по умолчанию его аксессоры set и get также становятся открытыми (public). Тем не менее для аксессора set или get можно указать собственный мо­дификатор доступа, например private. Но в любом случае доступность аксессора, определяемая таким модификатором, должна быть более ограниченной, чем доступ­ность, указываемая для его свойства или индексатора.

Существует целый ряд причин, по которым требуется ограничить доступность ак­сессора. Допустим, что требуется предоставить свободный доступ к значению свойства, но вместе с тем дать возможность устанавливать это свойство только членам его класса. Для этого достаточно объявить аксессор данного свойства как private. В приведен­ном ниже примере используется свойство MyProp, аксессор set которого указан как private.

Листинг 10.9

// Применить модификатор доступа в аксессоре

 

using System; 

 

class PropAccess

{  

int prop; // Поле, управляемое свойством MyProp 

 

public PropAccess() { prop = 0; } 

 

/* Это свойство обеспечивает доступ к закрытой переменной

экземпляра prop. Оно разрешает получать значение переменной

prop из любого кода, но устанавливать его – только

членам своего класса. */ 

public int MyProp

get { 

return prop; 

private set { // теперь это закрытый аксессор 

prop = value; 

}  

 

// Этот член класса инкременирует значение свойства MyProp.

public void IncrProp() {

MyProp++; // Допускается в том же самом классе

}

}  

 

// Продемонстрировать применение модификатора доступа в аксессоре

// свойства

class PropAccessDemo

{  

static void Main()

{  

PropAccess ob = new PropAccess(); 

 

Console.WriteLine("Первоначальное значение ob.MyProp: " +

                  ob.MyProp); 

 

// ob.MyProp = 100; // Недоступно для установки

 

ob.IncrProp();

Console.WriteLine("Значение ob.MyProp после инкременирования:"

                 + ob.MyProp); 

}

В классе PropAccess аксессор set указан как private. Это означает, что он досту­пен только другим членам данного класса, например методу IncrProp(), но недосту­пен для кода за пределами класса PropAccess. Именно поэтому попытка Присвоить свойству ob.MyProp значение в классе PropAccessDemo закомментировано.

Вероятно, ограничение доступа к аксессорам оказывается наиболее важным для работы с автоматически реализуемыми свойствами. Как пояснялось выше, создать автоматически реализуемое свойство только для чтения или же только для записи нельзя, поскольку оба аксессора, get и set, должны быть указаны при объявлении такого свойства. Тем не менее добиться желаемого результата все же можно, объявив один из аксессоров автоматически реализуемого свойства как private. В качестве примера ниже приведено объявление автоматически реализуемого свойства Length для класса FailSoftArray, которое фактически становится доступным только для чтения.

public int Length { get; private set; }

Свойство Length может быть установлено только из кода в его классе, поскольку его аксессор set объявлен как private. А изменять свойство Length за пределами его класса не разрешается. Это означает, что за пределами своего класса свойство, по существу, оказывается доступным только для чтения. Аналогичным образом можно объявить и свойство Error, как показано ниже.

public bool Error { get; private set; }

Благодаря этому свойство Error становится доступным для чтения, но не для уста­новки за пределами класса FailSoftArray.

Для опробования автоматически реализуемых вариантов свойств Length и Error в классе FailSoftArray удалим сначала переменные len и ErrFlag, поскольку они больше не нужны, а затем заменим каждое применение переменных len и ErrFlag свойствами Length и Error в классе FailSoftArray. Ниже приведен обновленный вариант класса FailSoftArray вместе с методом Main(), демонстрирующим его применение.

Листинг 10.10

// Применить автоматически реализуемые и доступные

// только для чтения свойства Length и Error

 

using System;

 

class FailSoftArray

int[] a; // ссылка на базовый массив 

 

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

public FailSoftArray(int size)

{

a = new int[size];

Length = size; 

}

 

// Автоматически реализуемое и доступное только для чтения

// свойство Length

public int Length { get; private set; }

 

// Автоматически реализуемое и доступное только для чтения

// свойство Error

public bool Error { get; private set; }

 

// Этот индексатор для массива FailSoftArray

public int this[int index]

{

// Это аксессор get

get

{

if(ok(index))

{

   Error = false;

   return a[index];

}

else

{

   Error = true;

   return 0;

}

}

 

// Это аксессор set

set

{

if(ok(index))

{

   a[index] = value;

   Error = false;

}

else Error = true;

}

}

 

// Возвратить логическое значение true, если

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

private bool ok(int index)

{

if(index >= 0 & index < Length) return true;

return false;

}

 

// Продемонстрировать применение усовершенствованного

// отказоустойчивго массива

class FinalFSDemo

static void Main()

FailSoftArray fs = new FailSoftArray(5);

 

// Использовать свойство Error

for(int i=0; i < fs.Length + 1; i++) {

fs[i] = i*10;

if(fs.Error) 

   Console.WriteLine("Ошибка в индексе " + i);

}

}

}

Этот вариант класса FailSoftArray действует таким же образом, как и предыду­щий, но в нем отсутствуют поддерживающие поля, объявляемые явно.

На применение модификаторов доступа в аксессорах накладываются следующие ограничения. Во-первых, действию модификатора доступа подлежит только один ак­сессор: set или get, но не оба сразу. Во-вторых, модификатор должен обеспечивать более ограниченный доступ к аксессору, чем доступ на уровне свойства или индексато­ра. И наконец, модификатор доступа нельзя использовать при объявлении аксессора в интерфейсе или же при реализации аксессора, указываемого в интерфейсе.



Поделиться:


Последнее изменение этой страницы: 2024-07-06; просмотров: 50; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 216.73.216.236 (0.007 с.)