Московский государственный университет имени М.В.Ломоносова
Опубликован: 01.11.2004 | Доступ: свободный | Студентов: 11298 / 459 | Оценка: 4.12 / 4.01 | Длительность: 19:20:00
ISBN: 978-5-9556-0077-9
Специальности: Программист
Лекция 17:

C#. Индексаторы класса и атрибуты

< Лекция 16 || Лекция 17: 1234 || Лекция 18 >
Аннотация: В лекции описывается создание и назначение индексаторов класса, вводится понятие методов аксессоров и элементов индексаторов. Приводится определение атрибута, рассматриваются типы атрибутов и их назначение, позиционные и именованные параметры атрибута, доступ к значению атрибута.

Индексаторы

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

Индексатор позволяет работать с классом или структурой таким образом, как если бы это были массивы. Индексация класса выполняется по индексу, указываемому как параметр. Иногда классы, используемые как индексаторы, называют классами-индексаторами.

Объявление индексатора может иметь следующее формальное описание:

[атрибуты] [модификаторы] тип this [[атрибуты] 
    тип_параметра идентификатор_параметра .,...]
        {объявление аксессоров}

Индексатор должен иметь как минимум один параметр. Тип и идентификатор параметра указываются в квадратных скобках после ключевого слова this.

Среда проектирования Visual Studio.NET позволяет использовать мастер создания индексатора: для этого в окне Class View следует выделить имя класса и выполнить команду контекстного меню Add|Add Indexer.

Диалог C# Indexer Wizard (рис. 17.1) позволяет определить параметры создаваемого индексатора.

Диалог C# Indexer Wizard

Рис. 17.1. Диалог C# Indexer Wizard

В поле Indexer Аcess указывается модификатор доступа для индексатора. Это могут быть следующие модификаторы:

  • public - доступ не ограничен;
  • protected - доступ ограничен только наследуемыми классами;
  • internal - доступ ограничен рамками текущего проекта;
  • private - доступ ограничен рамками данного класса;
  • protected internal - ограничение доступа наследуемыми классами текущего проекта.

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

  • bool - логическое значение true или false;
  • decimal - 128-битовый тип данных (1,0 * 10-28 до 7,9 * 1028);
  • int - 32-битовое целочисленное значение;
  • sbyte - знаковое 8-битовое целое (от - 128 до 127);
  • uint - беззнаковое 32-битовое целочисленное значение (от 0 до 4 294 967 295);
  • byte ;
  • double - 64-битовый тип данных (±5,0 * 10-324 до ±1,7 * 10308);
  • long - 64-битовое целочисленное значение;
  • string ;
  • ulong ;
  • char ;
  • float - 32-битовый тип данных (±1.5 * 10-45 до ±3.4 * 1038);
  • object ;
  • short ;
  • ushort.

Поле Parameter Name содержит имя параметра.

На панели Indexer Modifiers можно выбрать одну из следующих опций:

  • None - индексатор не содержит дополнительных модификаторов;
  • Virtual - реализация индексатора может быть переопределена в наследуемых классах, для индексатора указывается ключевое слово virtual;
  • Abstract - индексатор является членом абстрактного класса, для индексатора указывается ключевое слово abstract.

Ключевое слово this используется как имя индексатора, так как с классом, содержащим индексатор, можно манипулировать как с массивом.

Например:

public int this[int ind1]  // Индексатор типа int
                  // с одним параметром типа int - ind1
    {  get    {  return 0;   }
      set    {         }
    }

Методы-аксессоры

После определения параметра в фигурных скобках указаны два метода-аксессора. get-аксессор возвращает значение данных по указанному индексу,а set-аксессор устанавливает значение данных с указанным индексом. Устанавливаемое значение задается ключевым словом value.

Индексатор устанавливает и возвращает значения некоторого массива. Такой массив для аксессора должен быть создан. Типы используемого массива и аксессора должны совпадать. Например для целочисленного аксессора можно объявить следующий массив:

private int [] imyArray = new int[50];

Теперь, чтобы использовать акссессор, следует:

  1. определить возвращаемое методом-аксессором значение (например: return imyArray[ind1] ;);
  2. определить устанавливаемое методом-аксессором значение (например: imyArray[ind1]= value ;).

В результате класс, содержащий аксессор, будет иметь следующее объявление:

public class AClass1
  {
  public AClass1() {  }
      private int [] imyArray = new int[20]; 
  
  public int this[int ind1]
     {
    get
    { return imyArray[ind1]; }
    set
    { imyArray[ind1]= value; }
     }
  }

Элементы индексатора

Объект класса, используемого как аксессор, создается обычным образом. Инициализация элементов аксессора указывается как присвоение значений элементам массива. Доступ к элементам аксессора записывается как доступ к элементам массива.

Например:

AClass1 ac1= new AClass1();
  ac1[0]=5;
  ac1[1]=6;
  Console.WriteLine("ac1[0]= {0}, ac1[1]= {1}", 
                          ac1[0],ac1[1]);

Индексаторы на базе многомерных массивов

Для одного класса может быть создано несколько индексаторов. Индексаторы должны различаться числом параметров.

Например:

public class AClass1
 {   public AClass1() {   }
     private int [] imyArray = new int[20]; 
     public int this[int ind1]
  {  get { return imyArray[ind1];   }
    set { imyArray[ind1]= value; }
    }
     private int [,] imyArray2 = new int[2,10]; 
     public int this[int ind1, int ind2]
  {  get {return imyArray2[ind1,ind2]; }
    set {imyArray2[ind1,ind2]= value; }
  }
 }
< Лекция 16 || Лекция 17: 1234 || Лекция 18 >
Александр Демьяненко
Александр Демьяненко

Можно ли сдавать один и тот же тест несколько раз?
Или же один и тот же тест можно сдать лишь однажды?

Максим Стогний
Максим Стогний

Добрый день!

Скажите, пожалуйста, если в терминологии объектно-ориентированного программирования функции также называются методами или методами - членами класса, в примере объявления указателя на метод использовали в формальном описании оба названия:

тип_метода (имя_класса::*имя_метода_указателя)
    (список параметров);
тип_функции (*имя_ функции_указателя)
    (список параметров);

при этом можно было  тип_функции во втором описании заменить на тип_метода? Т.е.:

тип_метода (*имя_ метода_указателя)
    (список параметров);