Реферат: Введение в C#: классы
Программа выводит сообщение «Property Demo», используя различные цвета символов (от темно-синего до белого). Давайте попробуем разобраться в том, как она работает. Итак, сначала мы импортируем важные для нас функции API-интерфейса Windows: SetConsoleTextAttribute и GetStdHandle. К сожалению, стандартный класс среды .NET под названием Console не имеет средств управления цветом вывода текстовой информации. Надо полагать, что корпорация Microsoft в будущем все-таки решит эту проблему. Пока же для этих целей придется воспользоваться службой вызова платформы PInvoke (обратите внимание на использование атрибута DllImport). Далее, в конструкторе класса Screen мы получаем стандартный дескриптор потока вывода консольного приложения и помещаем его значение в закрытую переменную output_handle для дальнейшего использования функцией SetConsoleTextAttribute. Кроме этого, мы присваиваем другой переменной m_attributes начальное значение атрибутов экрана (7 соответствует белому цвету символов на черном фоне). Заметим, что в реальных условиях стоило бы получить текущие атрибуты экрана с помощью функции GetConsoleScreenBufferInfo из набора API-интерфейса Windows. В нашем же случае это несколько усложнило бы пример и отвлекло от основной темы.
В классе Screen мы объявили свойство Attributes, для которого определили функцию чтения (getter) и функцию записи (setter). Функция чтения не выполняет каких-либо специфических действий и просто возвращает значение поля m_attributes (в реальной программе она должна бы возвращать значение атрибутов, полученное с помощью все той же GetConsoleScreenBufferInfo). Функция записи несколько сложнее, так как кроме тривиального обновления значения m_attributes она вызывает функцию SetConsoleTextAttribute, устанавливая заданные атрибуты функций вывода текста. Значение устанавливаемых атрибутов передается специальной переменной value. Обратите внимание на то, что поле m_attributes является закрытым, а стало быть, оно не может быть доступно вне класса Screen. Единственным способом чтения и/или изменения этого метода является свойство Attributes.
Свойства позволяют не только возвращать и изменять значение внутренней переменной класса, но и выполнять дополнительные функции. Так, они позволяют произвести проверку значения или выполнить иные действия, как показано в вышеприведенном примере.
В языке C# свойства реализованы на уровне синтаксиса. Более того, рекомендуется вообще не использовать открытых полей классов. На первый взгляд, при таком подходе теряется эффективность из-за того, что операции присваивания будут заменены вызовами функций getter и setter. Отнюдь! Среда .NET сгенерирует для них соответствующий inline-код.
Делегаты
Язык программирования C# хотя и допускает, но все же не поощряет использование указателей. В некоторых ситуациях бывает особенно трудно обойтись без указателей на функции. Для этих целей в C# реализованы так называемые делегаты (delegates), которые иногда еще называют безопасными аналогами указателей на функцию. Ниже приведен простейший пример использования метода-делегата:
using System;
delegate void MyDelegate();
class Example_5
{
static void Func()
{
System.Console.WriteLine(«MyDelegate.Func()»);
}
public static void Main()
{
MyDelegate f = new MyDelegate(Func);
f();
}
}
Помимо того что делегаты обеспечивают типовую защищенность, а следовательно, и повышают безопасность кода, они отличаются от обычных указателей на функции еще и тем, что являются объектами, производными от базового типа System.Delegate. Таким образом, если мы используем делегат для указания на статический метод класса, то он просто связывается с соответствующим методом данного класса. Если же делегат указывает на нестатический метод класса, он связывается уже с методом экземпляра такого класса. Это позволяет избежать нарушения принципов ООП, поскольку методы не могут быть использованы отдельно от класса (объекта), в котором они определены.
Еще одним отличием делегатов от простых указателей на функции является возможность вызова нескольких методов с помощью одного делегата. Рассмотримэтонаконкретномпримере:
using System;
delegate void MyDelegate(string message);
class Example_6
{
public static void Func1(string message)
{
Console.WriteLine(”{0}: MyDelegate.Func1”, message);
}