Студопедия
Случайная страница | ТОМ-1 | ТОМ-2 | ТОМ-3
АрхитектураБиологияГеографияДругоеИностранные языки
ИнформатикаИсторияКультураЛитератураМатематика
МедицинаМеханикаОбразованиеОхрана трудаПедагогика
ПолитикаПравоПрограммированиеПсихологияРелигия
СоциологияСпортСтроительствоФизикаФилософия
ФинансыХимияЭкологияЭкономикаЭлектроника

Механизм вызова событий

Типичные ошибки при работе со ссылками | Понятие автоматического указателя (auto_ptr) | Перегрузка операторов преобразования типа | Специализации шаблонов | Assert срабатывает только в режиме Debug | Потоки ввода-вывода | Автоматическое управление памятью ссылочных данных | Упаковка и разупаковка данных | Типы данных со значением null | Конструкторы и деструкторы |


Читайте также:
  1. IV этап(с середины XX в. по настоящее время)– психология как наука, изучающая факты, закономерности и механизмы психики
  2. Агроөнеркәсіптік кешенді мемлекеттік реттеудің бағыты, әдістері және нақты механизмдері
  3. Административный механизм управления энергосбережением
  4. Анатомо-физиологическое обоснование массажа, механизм его действия на организм человека
  5. Аппаратные средства поддержки многозадачной работы микропроцессора. Структура таблици состояния задач. Алгоритмы и механизмы переключения задач
  6. Барьерные методы контрацепции. Механизм действия. Показания и противопоказания, побочные действия. Способ применения.
  7. Биологические ритмы и их механизмы (13, 24)

 

The List<T> class declares a single event member called Changed, which indicates that a new item has been added to the list. The Changed event is raised by the OnChanged virtual method, which first checks whether the event is null (meaning that no handlers are present). The notion of raising an event is precisely equivalent to invoking the delegate represented by the event—thus, there are no special language constructs for raising events.

Clients react to events through event handlers. Event handlers are attached using the += operator and removed using the -= operator. The following example attaches an event handler to the Changed event of a List<string>.

using System;

class Test
{
static int changeCount;

static void ListChanged(object sender, EventArgs e) {
changeCount++;
}

static void Main() {
List<string> names = new List<string>();
names.Changed += new EventHandler(ListChanged);
names.Add("Liz");
names.Add("Martha");
names.Add("Beth");
Console.WriteLine(changeCount); // Outputs "3"
}
}

For advanced scenarios where control of the underlying storage of an event is desired, an event declaration can explicitly provide add and remove accessors, which are somewhat similar to the set accessor of a property.

 


24. Обобщенные классы в языке C# и их отличие от шаблонов классов в языке C++. Установка ограничений на параметры обобщенных классов. Обобщенные делегаты.

 

Обобщенные классы в языке C# и их отличие от шаблонов классов в языке C++

Обобщенные типы присутствуют во многих библиотеках базовых классов.NET, но пространство имен System.Collections.Generic буквально наполнено ими. Подобно своему “родственнику” без обобщений (System.Collections), пространство имен System.Collections.Generic содержит множество типов класса и интерфейса, что позволяет вкладывать элементы в самые разные контейнеры.

ПРИМЕЧАНИЕ По соглашению для обобщенных типов их замещаемые параметры обозначаются буквами верхнего регистра. И хотя здесь допустимо использовать любые буквы (или слова), обычно используют T для обозначения типов, K — для ключей, а V — для значений.

В пространстве имен System.Collections.Generic определяется и ряд классов, реализующих многие из этих ключевых интерфейсов.

Обобщенный класс Необобщенный аналог в System.Collections Описание
Collection<T> CollectionBase База для обобщенной коллекции
Comparer<T> Comparer Выполняет сравнение двух обобщенных объектов
Dictionary<K, V> Hashtable Обобщенная коллекция пар имен и значений
List<T> ArrayList Список элементов с динамически изменяемыми размерами
Queue<T> Queue Обобщенная реализация списка FIFO (дисциплина обслуживания типа “очередь”)
SortedDictionary<K, V> SortedList Обобщенная реализация сортированного набора пар имен и значений
Stack<T> Stack Обобщенная реализация списка LIFO (дисциплина обслуживания типа “стек”)
LinkedList<T> Обобщенная реализация двусвязного списка
ReadOnlyCollection<T> ReadOnlyCollectionBase Обобщенная реализация набора элементов только для чтения

Тип List<T>

Подобно необобщенным классам, обобщенные классы являются объектами, размещаемыми в динамической памяти, поэтому для них следует использовать new со всеми необходимыми аргументами конструктора. Кроме того, вы должны указать типы, замещающие параметры, определенные обобщенным типом. Так, для System.Collections.Generic.List<T> требуется указать одно значение, задающее вид элемента, с которым будет функционировать List<T>. Например, чтобы создать три объекта List<> для хранения целых чисел, объектов SportsCar и объектов Person, вы должны записать следующее.

static void Main(string[] args){ // Создается List для хранения целых чисел. List<int> myInts = new List<int>(); // Создается List для хранения объектов SportsCar. List<SportsCar> myCars = new List<SportsCar>(); // Создается List для хранения объектов Person. List<Person> myPeople = new List<Person>(); }

Когда вы создаете тип List<T> и указываете для него SportsCar, это эквивалентно следующему определению типа List<T>.

namespace System.Collections.Generic{ public class List<SportsCar>: IList<SportsCar>, ICollection<SportsCar>, IEnumerable<SportsCar>, IList, ICollection, IEnumerable {... public void Add(SportsCar item); public IList<SportsCar> AsReadOnly(); public int BinarySearch(SportsCar item); public bool Contains(SportsCar item); public void CopyTo(SportsCar[] array); public int FindIndex(System.Predicate<SportsCar> match); public SportsCar FindLast(System.Predicate<SportsCar> match); public bool Remove(SportsCar item); public int RemoveAll(System.Predicate<SportsCar> match); public SportsCar [] ToArray(); public bool TrueForAll(System.Predicate<SportsCar> match); public SportsCar this[int index] { get; set; }... }}

 

// Этот метод переставляет любые два элемента, // определенные параметром типа <T>. static void Swap<T>(ref T a, ref T b) { T temp; temp = a; a = b; b = temp; }

Swap<int>(ref a, ref b);

При вызове обобщенных методов, подобных Swap<T>, у вас есть возможность не указывать параметр типа, но только в том случае, когда обобщенный метод требует указания аргументов, поскольку тогда компилятор может “выяснить” тип этих аргументов на основе вводимых параметров.

// Компилятор будет предполагать System.Boolean. bool b1 = true, b2 = false; Console.WriteLine("До обмена: {0}, {1}", b1, b2); Swap(ref b1, ref b2); Console.WriteLine("После обмена: {0}, {1}", b1, b2);

Но если, например, у вас есть обобщенный метод с именем DisplayBaseClass<T>, не имеющий входных параметров, как показано ниже:

static void DisplayBaseClass<T>(){ Console.WriteLine("Базовым классом {0} является: {1}.", typeof(T), typeof(T).BaseType); }

то при вызове этого метода вы должны указать параметр типа.

В данном случае обобщенные методы Swap<T> и DisplayBaseClass<T> были определены в рамках объекта приложения (т.е. в рамках типа, определяющего метод Main()). Если вы предпочтете определить эти члены в новом типе класса (MyHelperClass), то должны записать следующее.

public class MyHelperClass{ public static void Swap<T>(ref T a, ref T b) { Console.WriteLine("Методу Swap() передано {0}", typeof(T)); T temp; temp = a; a = b; b = temp; } public static void DisplayBaseClass<T>() { Console.WriteLine("Базовым классом {0} является: {1}.", typeof(T), typeof(T).BaseType); }}

Обратите внимание на то, что тип MyHelperClass сам по себе не является обобщенным, но определяет два обобщенных метода. Так или иначе, теперь, когда методы Swap<T> и DisplayBaseClass<T> находятся в контексте нового типа класса, при вызове их членов придется указать имя типа.

MyHelperClass.Swap<int>(ref a, ref b);

Наконец, обобщенные методы не обязаны быть статическими. Если бы Swap<T> и DisplayBaseClass<T> были методами уровня экземпляра, нужно было бы просто создать экземпляр MyHelperClass и вызвать их из объектной переменной.

MyHelperClass c = new MyHelperClass(); c.Swap<int>(ref a, ref b);

 

 

// Обобщенная структура Point.public struct Point<T>{ // Обобщенные данные. private T xPos; private T yPos; // Обобщенный конструктор. public Point(T xVal, T yVal) { xPos = xVal; yPos = yVal; } // Обобщенные свойства. public T X { get { return xPos; } set { xPos = value; } } public T Y { get { return yPos; } set { yPos = value; } } public override string ToString() { return string.Format("[{0}, {1}]", xPos, yPos); } // Переустановка полей со значениями параметра типа, // принятыми по умолчанию. public void ResetPoint() { xPos = default(T); yPos = default(T); }}

В C# 2005 ключевое слово default получило два значения. Кроме использования в конструкции switch, оно может использоваться для установки параметрам типа значений, принятых по умолчанию. И это, очевидно, полезно, поскольку обобщенный тип ничего заранее не знает о фактических замещающих значениях и поэтому не может с безопасностью предполагать о том, каким должно быть значение по умолчанию. Значения по умолчанию для параметра типа являются следующими.


Дата добавления: 2015-11-16; просмотров: 83 | Нарушение авторских прав


<== предыдущая страница | следующая страница ==>
Частично определяемые классы и их назначение| Создание пользовательских обобщенных коллекций

mybiblioteka.su - 2015-2024 год. (0.007 сек.)