Студопедия

КАТЕГОРИИ:


Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748)

Семейства с доступом по ключу и интерфейс IDictionary

Public class Animals: CollectionBase//собственное семейство

Пример с использованием собственного семейства

public abstract class Animal

{

protected string name;

public string Name

{

get

{return name;}

set

{name = value;}

}

public Animal()

{name = "У животного нет имени";}

public Animal(string newName)

{name = newName;}

public void Feed()

{Console.WriteLine("{0} кушает", name);}

}

public class Cow: Animal

{

 

public void Milk()

{Console.WriteLine("{0} дает молоко", name);}

public Cow(string newName): base(newName)

{}

}

public class Chicken: Animal

{

public void LayEgg()

{

Console.WriteLine("{0} несет яйца", name);

}

public Chicken(string newName): base(newName)

{}

}

{

public void Add(Animal newAnimal)

{List.Add(newAnimal);}

public void Remove(Animal oldAnimal)

{

List.Remove(oldAnimal);

}

public Animals()

{

}

public Animal this[int animalIndex]

{

get

{

return (Animal)List[animalIndex];

}

set

{

List[animalIndex] = value;

}

}

}

class Class

{

static void Main(string[] args)

{

Console.WriteLine("Использование семейства для class Animals:");

Animals animalCollection = new Animals();

animalCollection. Add (new Cow ("Новая Буренка"));

animalCollection.Add(new Chicken("Новая Курица"));

foreach (Animal myAnimal in animalCollection)

{

Console.WriteLine("Новый {0} объект добавлен в семейство " + " Name = {1}", myAnimal.ToString(), myAnimal.Name);

}

animalCollection[0].Feed(); //теперь так можно обратиться к элементам семейства

((Cow)animalCollection[0]).Milk();

((Chicken)animalCollection[1]).LayEgg();

}

Кроме интерфейса IList, в семействах можно реализовать аналогичный интерфейс IDictionary, который позволяет осуществлять доступ к элементам по значению ключа (например, по строке с именем) вместо доступа по индексу. Это тоже достигается с помощью индексатора, однако в данном случае параметр индексатора привязывается к хранящемуся элементу, а не к индексу типа int, что позволяет сделать семейство несколько более дружественным по отношению к пользователю. Точно так же, как и для индексируемых семейств, в данном случае имеется базовый класс, который можно использовать для упрощения реализации интерфейса IDictionary— класс DictionaryBase.

Класс DictionaryBase, как и класс ColllectionBase, реализует некоторые (но не все) члены, полученные посредством поддерживаемых им интерфейсов. Так же, как и в классе CollectionBase, в нем реализованы методы Clear() и Count(), а вот метод RemoveAt() — нет.. Однако IDictionary обладает методом Remove(), являющимся одним из тех методов, которые необходимо реализовать для создаваемых пользователем классов семейств, основанных на классе DictionaryBase.

Следующий код являет собой пример альтернативной версии класса Animals из предыдущего примера, который на этот раз в качестве базового класса использует класс DictionaryBase. В него входят методы Add(), Remove() и индексатор доступа по ключу:

public class Animals: DictionaryBase

{

public void Add(string newID, Animal newAnimal)

{

Dictionary.Add(newID,newAnimal);

}

public void Remove(string animalID)

{

Dictionary.Remove(animalID);

}

public Animals() {}

public Animal this[string animalID]

{

get {return (Animal)Dictionary[animalID];}

set {Dictionary[animalID]=value;}

}

foreach (DictionaryEntry my in AnimalCollection)

{

Console.WriteLine(“Новый {0} объект добавлен в семейство” + “Name={1}”,my.Value.ToString(), ((Animal)my.Value).Name);

}

В данном примере метод Add() принимает два параметра: ключ и значение, которые будут храниться совместно. Данная реализация предусматривает передачу значения типа string в качестве ключа и передачу объекта типа Animal.

Метод Remove() получает в качестве параметра ключ, а не ссылку на объект. Элемент, обладающий значением, заданным с помощью ключа, удаляется.

Индексатор использует вместо индекса значение ключа в виде строки, что позволяет осуществлять доступ к хранящемуся элементу через наследуемый член Dictionary. В данном случае приведение типа является обязательным.

Еще одним отличием семейств с базовым классом DictionaryBase от семейств с базовым классом CollectionBase является то, что для них немного по-разному выполняется конструкция foreach. Использование конструкции foreach с классом, производным от DictionaryBase приводит к получению типа DictionaryEntry — еще одного типа, описанного в пространстве имен System.Collections. Для того чтобы добраться до самих объектов типа Animal, необходимо воспользоваться членом этой структуры value.

Индексаторы и пользовательские классы

Индексаторы используются также с “обычными классами”, то есть индексаторы работают не только с семействами. Например, если у класса есть скрытое поле, представляющее собой массив, то с помощью индексатора можно обратиться к элементу этого массива, используя имя экземпляра класса и номер элемента массива в квадратных скобках. То есть индексатор - это такой “умный” индекс для экземпляров класса.

Пример программы класса “Одномерный массив”, элементы которого должны находиться в диапазоне от 0 до 100. Кроме того, при доступе к элементу проверяется, не вышел ли индекс за допустимые границы.

namespace ConsoleApplication1

{ class MyArray

{ public MyArray(int size) //конструктор инициализации

// задает кол-во элементов массива

{length = size; a = new int[length];}

public int Length //свойство-размерность

{ get { return Length; } }

public int this[int i] //индексатор

{get

{//проверка на допустимые границы по размерности

if (i >= 0 && i < length) return a[i];

else { error = true; return 0; }

}

set {//проверка на допустимые границы по значениям (от 0 до 100)

if (i >= 0 && i < length && value>=0 && value<=100) a[i]=value;

else error = true; }

}

//поля класса, данное error-признак ошибки

public bool error = false;

int []a;

int length;

}

class Program

{static void Main(string[] args)

{ int n = 100;

MyArray mas = new MyArray(n); //создание экземпляра

for (int i = 0; i < n; i++)

{

/*/ mas[i] = i * 2; //задание элементам массива значений

/**/ Console.Write(mas[i]+" ");

}

Console.WriteLine();

//если происходил выход за пределы – данное error имеет значение true

if (mas.error) Console.WriteLine(" Были обнаружены ошибки!!!");

Console.ReadKey();

}

}

}

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

Если обращение к экземпляру встречается в левой части оператора присваивания (/*/), то автоматически вызывается часть get. Если обращение происходит в составе выражения (/**/), то вызывается часть set.

В классе MyArray если при попытке записи элемента массива его индекс или значения заданы не верно, то значение элементу не присваивается, если при попытке чтения элемента индекс не в допустимом диапазоне, возвращается 0, значение поля error принимается true.

 

<== предыдущая лекция | следующая лекция ==>
Set код_доступа | Переработка лекарственного растительного сырья. Требования, предъявляемые к созданию новых лекарственных средств
Поделиться с друзьями:


Дата добавления: 2014-01-20; Просмотров: 337; Нарушение авторских прав?; Мы поможем в написании вашей работы!


Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет



studopedia.su - Студопедия (2013 - 2024) год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! Последнее добавление




Генерация страницы за: 0.027 сек.