Главная » C#, Компоненты » Свойства и события

0

Любой компонент взаимодействует с внешним миром с помощью свойств и событий. Свойства (properties) позволяют настраивать и получать параметры компонента, а события (events)— реагировать на происходящие внутри компонента события, программировать реакцию компонента на внешние события и т. д.

С точки зрения кода, события — сокращенная запись методов. Рассмотрим, например, такой код:

class Test {

private int testlnt;

public int Testlnt {

get { return testlnt; } set { testInt = value; }

}

}

Этот фрагмент можно было бы написать так:

class Test {

private int testlnt;

public int GetTestlnt() {

return testlnt;

}

public void SetTestlnt(int value) {

testlnt = value;

}

}

Таким образом, запись в виде свойства уменьшает количество кода, оставляя основное преимущество свойств— возможность дополнительных действий при получении или записи значения поля. Действительно, доступ к обычному полю не дает никакой возможности, например, проверить значение на правильность. Сравните два фрагмента кода:

// Доступ к ПОЛЮ

class Test {

public int testlnt;

}

int v = testlnt;

// Доступ к свойству

class Test {

private int testlnt;

public int Testlnt {

get { return testlnt; } set {

if (testlnt < 0)

throw new ArgumentOutOfRangeException("Testlnt");

testlnt = value;

}

}

}

Дополнительная проверка во время установки значения свойства позволяет отсечь некорректные значения. Аналогичный код для поля нужно было бы писать во всех местах, где производится установка значения этого поля.

Методы get и set, которые, по сути, являются оболочкой поля, называют ак- сессорами (accessor). Еще одно преимущество свойств— возможность задавать разный уровень доступа аксессоров:

class Test {

private int testlnt;

public int Testlnt {

get { return testlnt; } protected set { testlnt = value; }

}

}

Здесь, аксессор get получает уровень видимости public, тогда как set ограничивается уровнем protected. Извне такое свойство будет выглядеть как свойство "только для чтения".

Кажется, информации о свойствах у нас вполне достаточно, перейдем к событиям.

Модель событий (event) в .NET основана на делегатах (delegate). Делегаты позволяют обращаться к методам обратного вызова (callback method). Метод обратного вызова — это механизм, позволяющий объекту получать уведомления, на которые он подписался.

Описание события производится с помощью специального слова event:

public class TestClass (

private event EventHandler OnChange;

public event EventHandler OnChange {

add { onChange += value; } remove { onChange -= value; }

По виду записи события похожи на свойства. Метод add позволяет подписать объект на событие, а метод remove — удалить подписку.

Тот же самый код будет сгенерирован, если описать событие с модификатором public."

public class TestClass {

public event EventHandler OnChange;

}

Методы add, remove и закрытое поле делегата будут сгенерированы компилятором автоматически.

Когда компоненту нужно вызвать событие, используется следующий код:

if (onChange != null)

onChange(this, new EventArgs());

Проверка на null позволяет обработать ситуацию, когда обработчик события не задан.

Класс EventHandler описывает тип события. Его определение выглядит так:

public delegate void EventHandler(object sender, EventArgs e) ;

Можно сказать, что по умолчанию (т. е. при использовании типа EventHandler) у события будут два аргумента. Параметр sender определяет "владельца" события, и поэтому при вызове события обычно передается значение this. Второй параметр представляет собой пустой аргумент, описываемый с помощью класса EventArgs:

public class EventArgs {

public static readonly EventArgs Empty; public EventArgs();

}

Конечно, параметры события не всегда столь примитивны. При необходимости передать больше информации в параметрах нужно создать собственный наследник класса EventArgs и описать соответствующий тип параметра:

// Описание аргумента с параметром Name

public class ChangeArgs : EventArgs {

private readonly string name;

public ChangeArgs(string name)

j

this.name = name ;

}

public string Name (

get { return name; }

}

}

// Описание события

public event EventHandler<ChangeArgs> OnChange; // Вызов события if (OnChange != null)

OnChange(this, new ChangeArgs(this.Name));

Сам обработчик события будет выглядеть, например, так:

private void gradientLabell_OnChange(object sender,

MyControl.ChangeArgs e)

{

// Обработка

}

Реализация методов add и remove самостоятельно нужна, например, если необходимо создать потокобезопасный код (как я уже говорил, по умолчанию можно оставить работу по генерации этих методов компилятору):

// Описание объекта синхронизации

private readonly object eventLock = new object();

// Закрытый делегат

private EventHandler<ChangeArgs> onChange;

// Описание события (методы add и remove) public event EventHandler<ChangeArgs> OnChange (

add (

lock (eventLock) {

onChange += value;

remove {

lock (eventLock) {

onChange -= value;

}

}

}

// Вызов события if (onChange != null)

onChange(this, new ChangeArgs(this.Name));

Это все, что я хотел рассказать о свойствах и событиях. Конечно, я понимаю, что это очень мало, но, согласитесь, что эту информацию вполне можно найти во многих источниках, например в MSDN или в [5].

Литература:

Агуров П. В. C#. Разработка компонентов в MS Visual Studio 2005/2008. – СПб.: БХВ-Петербург, 2008. — 480 е.: ил.

По теме:

  • Комментарии