Каждый наш учебный листинг начинается с using, т.е. определения видимых пространств имен. Можем ли мы создавать свои пространства имен? Почему бы и нет? Давайте копнем, как этот механизм устроен... Для создания используется ключевое слово namespace. Внутри него могут содержаться классы, структуры и т.д. И все они будут видимы в своем пространстве имен. Чтобы не писать много раз название пространства имен, мы пользуемся директивой using. Как и весь C#, это предельно просто:)

namespace Units
{
class CPU
{
public char ID;
public int freq;
public int CACHE;
}
}

class Application
{
public static void Main()
{
Units.CPU object1=new Units.CPU();
object1.ID='A';
object1.freq=1700;
object1.CACHE=256;
System.Console.WriteLine("Made by "+object1.ID);
System.Console.WriteLine("Frequence is"+object1.freq+"Mhz");
System.Console.WriteLine("CACHE has "+object1.CACHE+"Kb");
System.Console.ReadLine();
}
}

Класс CPU виден в пространстве имен Units, и для создания объекта приходится набирать:

Units.CPU object1=new Units.CPU();

От этого мы можем избавиться при помощи директивы using, в начале исходника
пишем:

using Units;

и можем смело создавать объект так:

CPU object1=new CPU();

Директиву using можно использовать и с другой целью – создание псевдоимен. Во многих листингах вы видели:

using Sc=System.Console;

Здесь Sc – псевдоимя, под которым видно пространство имен System.Console. В таком контексте справа от знака ‘=’ может быть пространство имен или класс. Все, typedef нам ни к чему. Хотя когда-нибудь, как-нибудь, где-нибудь да пригодится, забывать не стоит.

Далее мы рассмотрим более специфичные элементы языка – делегаты и события. Делегатом в C# называется объект, содержащий ссылку на метод. Делегаты аналогичны указателям на функции в классических языках. На более низком уровне, делегат содержит адрес метода в памяти, этот адрес также называют точкой входа метода. Делегаты могут содержать ссылки на методы объектов или на статические методы класса. Статические методы могут быть вызваны, даже если не создан объект класса, для их объявления применяется ключевое слово static, следующее за модификатором доступа. Для объявления делегатов используется ключевое слово delegate. Делегат может содержать только ссылку на метод, возвращаемый тип и список аргументов которого совпадают с объявлением делегата.

Вот общий формат объявления делегата:

delegate тип имя(список_аргументов);

Затем следует создать объект делегата, следующим образом:

имяДелегата имяОбъекта = new имяДелегата (имяМетода);

А вот теперь действительно интересное -> делегат может содержать как одну, так и несколько ссылок на разные методы. И реализуется это очень просто – операторы ‘+=’ и ‘-=’. Их формат:

имяОбъектаДелегата +=имяДобавочногоДелегата;
имяОбъектаДелегата -=имяУдаляемогоДелегата;

Так создаются многоадресные делегаты. Нужен ли пример? Ну давайте сварганим.

using Sc=System.Console;

delegate void IO();//объявляем делегат

class Matrix// класс матрицы
{
private int[,] element=new int[4,4];

public int GetValue(int ii,int jj)
{return element[ii,jj];} 

public void Scan()
{
int i,j,ii;
for(i=0;i<4;i++)
{
string str1;
ii=i+1;
Sc.WriteLine("Enter string #"+ii);
for(j=0;j<4;j++)
{
Sc.Write("Enter value for element["+i+","+j+"](then press 

Enter)=>");
str1=Sc.ReadLine();
element[i,j]=int.Parse(str1);
}
Sc.WriteLine();
}
}

public void Print()//вывод всей матрицы
{
int i,j;//
переменные для циклов
for(i=0;i<4;i++)
{
for(j=0;j<4;j++)
{
Sc.Write(" "+GetValue(i,j));
}
Sc.WriteLine();
}Sc.ReadLine();
}
}

class Application
{
public static void Main()
{
//
создаем объект класса
Matrix matrix1=new Matrix();
//
создаем объекты делегатов
IO Io=new IO(matrix1.Scan);
IO Out=new IO(matrix1.Print);
//
добавляем новый метод 
//
к последовательности ссылок
Io+=Out;
//
вызываем делегат
Io();

}

Следует обратить внимание на то, что для добавления метода к исполняемой цепочке делегата необходимо создать новый делегат, содержащий ссылку на этот метод, а затем прибавить новый делегат к старому. Для удаления делегата из цепочки его надо просто вычесть. Просто, не так ли? Делегаты позволяют выбирать метод на этапе выполнения программы в зависимости от той или иной ситуации. На основе делегатов создаются события и устанавливаются обработчики событий. Что же такое событие? Его можно рассмотреть, как сигнал о каком-либо действии, изменении... Ну а эти события созданы для того чтобы их обрабатывать. Обработкой событий занимаются специальные методы – обработчики. Как было сказано ранее, делегаты могут быть многоадресными, а значит и одно событие может иметь несколько обработчиков. Но как же с ними работать? C# предусматривает ключевое слово event для определения событий. Обычно события определяются как открытые члены класса. Давайте разберемся, как использовать этот механизм на примере простенькой проги. Создадим класс Number, главным членом которого будет являться целочисленная переменная, которая не может быть равна нулю. И если пользователь вводит 0, то происходит событие ввода нуля, которое нам надо, типа, обработать. А обработаем мы его так – просто выведем сообщение об ошибке. Итак, вникнем в код...

using Sc=System.Console;

delegate void Handle();//это делегат для нашего события

class Number
{
private int num;

private bool Verify(int n)//проверка на 0
{
if(n!=0) return true;
else return false;

public Number(){num=1;}

public Number(int n)
{if(n!=0) num=n;}

public event Handle isZero;//а это и есть событие

public void ZeroMsg()//сообщение 1
{Sc.WriteLine("0 can't be a number!");}

public void ErrorMsg()//сообщение 2
{
Sc.WriteLine("Critical Error!");
Sc.WriteLine("The program will be shut down!");
Sc.ReadLine();
}

public void Input()//ввод значения
{
string str;
bool v;
int n;

Sc.Write("Enter number:");
str=Sc.ReadLine();
n=int.Parse(str);
v=Verify(n);
//
если 0, то “запускаем” событие 
if(v==false) isZero();
//
иначе все нормально 
else 
{
num=n;
Sc.WriteLine("This one is OK!");
Sc.ReadLine();
}
}
}

class Application
{
public static void Main()
{
Number ob=new Number();
//
добавляем новые обработчики 
ob.isZero+=new Handle(ob.ZeroMsg);
ob.isZero+=new Handle(ob.ErrorMsg);

ob.Input(); 
}
}

В принципе, событие – это объект делегата. Физически этот объект делегата содержит ссылки на обработчики события. События, обрабатываемые более чем одним обработчиком, называются широковещательными. Для их поддержки рекомендуется определять делегат с пустым (void) типом возвращаемого значения. События и их обработка открывают новые горизонты во многих сферах ИТ, эти знания нам отлично помогут в написании “автоматизаторов” приложений.

  • Подпишись на наc в Telegram!

    Только важные новости и лучшие статьи

    Подписаться

  • Подписаться
    Уведомить о
    0 комментариев
    Межтекстовые Отзывы
    Посмотреть все комментарии